Top Front-End Tools Of 2023

Over the past 12 months, I’ve shared hundreds of tools in my newsletter, Web Tools Weekly. I feature tons of practical libraries, helpers, and other useful things for front-end and full-stack developers. These tools span numerous categories, including JavaScript libraries and utilities, web frameworks, CSS generators, database tools, React components, CLI tools, and even ChatGPT and AI-based tools, the latter of which I’ve started covering regularly over the past year.

The 60 tools in this article were some of the most clicked web developer tools in my newsletter in 2023. As you’ll see, most of these are quite practical for front-end and full-stack development, so you’ll likely find lots that you’ll want to bookmark or use in an upcoming project. The list is roughly in reverse order in terms of popularity, so be sure to scroll down to see what the most popular tools of the year were!

Kuma UI

Kuma UI, which describes itself as “the future of CSS-in-JS”, is a headless, utility-first, zero-runtime component library that includes its own CSS-in-JS solution.

What makes Kuma UI different is its hybrid approach that allows for dynamic changes to your styles at runtime while still keeping the performance benefits of zero-runtime CSS-in-JS.

Boxslider

Although the use of carousel components has been discouraged in recent years, they still get asked for by my clients, and developers are always on the lookout for them. Boxslider is one such component.

This carousel, or content slider, includes seven slide transition effects that you can try out on the demo page, including a 3D cube effect, tile flip, and a simple fade.

Effect

Effect is described as “a powerful TypeScript library designed to help developers easily create complex, synchronous, and asynchronous programs.”

The idea behind the effect is to help developers build robust and scalable applications by means of something called structured concurrency, a programming paradigm that allows multiple complex operations to run simultaneously.

HatTip

If you use Express.js for building Node.js apps, you’ll want to check out HatTip. It offers a solution similar to Express.js, but with a more universal approach.

HatTip is a set of JavaScript packages for building HTTP server apps and allows you to write server code that can be deployed anywhere – AWS, Cloudflare Workers, Vercel, and more.

LiveViewJS

LiveViewJS is a simple yet powerful framework for building “LiveViews” in Node.js and Deno. LiveViews were popularized in Elixir’s Phoenix framework and involved moving state management and event handling to the server and doing HTML updates via WebSockets.

This technique allows you to build single-page app experiences with features like fast first paint, real-time and multi-player functionality, no need for a client-side routing solution, and lots more.

Scrollbar.app

Scrollbar.app is a one-stop reference and code generation tool for customizing browser scrollbars. You can live test and adjust the scrollbars directly on the page, then copy the CSS.

The scrollbar code involves using vendor-specific pseudo-elements but also incorporates the future-friendly scrollbar-color.

OpenGPT

OpenGPT is one of many ChatGPT-based tools that have been making the rounds over the past year or so. This one is an open-source AI platform that allows anyone to use and create ChatGPT-based applications.

The main platform for the service itself allows you to search a categorized directory of more than 11,000 ChatGPT apps.

Free Icons

Icon sets always seem to make these end-of-year lists. Free Icons is a generically named set of 22,000+ icons that includes both brand icons and general-use ones.

All are in SVG format, and you can filter by keyword on the home page or grab the whole lot via the GitHub repository.

Materialize

Materialize is an open-source framework of UI components based on Google’s Material Design guidelines.

The project, which includes 20+ categories of components, is a fork of an older project that’s no longer maintained.

qr-code

qr-code is an SVG-based web component that generates an animatable and customizable QR code. There’s an interactive demo page where you can try out the different animation effects.

The resulting QR code is SVG-based, the component has no dependencies, and it is easy to customize.

GradientGenerator

GradientGenerator is an interactive CSS gradient builder that allows you to build advanced layered gradients. You can customize your layered gradient using a whole slew of different settings and features.

The app also allows you to save gradients to your library and even import community-built gradients.

iDraw.js

iDraw.js is a simple JavaScript framework for creating apps that allow Canvas-based drawing.

There are some nice examples in a live playground where you can see the simplicity and ease of use of the API.

VanJS

VanJS is a UI library similar to React but doesn’t use JSX, virtual DOM, transpiling, and so on. The idea is to avoid the overhead of configuration that’s normally associated with using a library like React.

The library claims to be the smallest UI library in the world at under 1kb. It has first-class support for TypeScript and naturally boasts strong performance compared to React, Vue, and so on.

Mamba UI

Mamba UI is the first of multiple Tailwind-based tools that made this year’s list. This is a UI library of 150+ components and templates based on the popular utility-first CSS framework.

The library includes pre-styled components in 40+ categories, and you can quickly grab the code for any component in HTML, Vue, or JSX format.

Termino.js

Termino.js is a dependency-free JavaScript component that lets you add embedded terminal-based animations, games, and apps to web pages.

It’s customizable and makes it easy to build terminal animations like keyboard typing effects. The demo page includes a few simple examples, including an embedded terminal app where the user can get info on any GitHub profile.

SVG Chart Generator

SVG Chart Generator is a beautifully designed chart generator that lets you generate SVG-based charts in line or bar format.

The generator allows you to interactively customize the chart with width/height settings, number of points, smoothness, and more. You can also import your own data points.

PeepsLab

PeepsLab is a simple online tool to customize your own unique illustrated user avatars. You can build your own avatars by cycling through the different options for skin color, hair color, facial hair, accessories, styles for head, face, etc.

Or you can simply hit the “Randomize” button to generate a random avatar before downloading it in PNG format.

Ribbon Shapes

Ribbon Shapes is an online gallery of pure CSS ribbons in just about any ribbon format you can imagine.

The gallery includes more than 100 ribbons, each created with a single HTML element and easy to customize using CSS variables.

big-AGI

big-AGI is a personal GPT-powered app that’s described as “the GPT application for professionals that need function, form, simplicity, and speed.”

It has a responsive, mobile-friendly interface and includes features like AI personas, text-to-image, voice, response streaming, code highlighting and execution, PDF import, and lots more.

Easy Email

Easy Email is a drag-and-drop email editor based on MJML, the popular HTML email authoring framework.

This solution allows you to transform structured JSON data into HTML that’s compatible with major email clients. Includes features for easily customizing blocks, components, and configuring themes.

CSS Components

CSS Components throws its hat into the CSS-in-JS space with this fresh solution, described as “not another styling system.”

This solution is a response to challenges inherent in using CSS-in-JS tools with React Server Components, and the library is inspired by another such tool, Stitches, and promises an improved developer experience.

Toaster

Toaster is an experimental pure CSS 3D editor that allows you to build models using pure HTML with CSS transforms.

The author acknowledges that the tool isn’t too practical and can currently only export/import in JSON format (no CSS export). With improved performance, this could be a useful tool.

Fontpair

Fontpair isn’t a new resource, but it makes this year’s list. It’s a font directory specifically for finding fonts that match well together in your designs.

All the fonts are sourced from Google Fonts, and the pairings are manually curated by the authors.

Breadit

Breadit is a modern, full-stack Reddit clone built with Next.js App Router, TypeScript, and Tailwind.

This is a nice app to learn and experiment with, featuring infinite scroll, NextAuth, image uploads, a feature-rich post editor, nested commenting, and lots more.

Keep React

Keep React is a Tailwind and React-based component library that includes 40+ components and interactive elements.

The components are pre-designed, but all the components are easy to customize using Tailwind classes and are suitable for just about any project.

TW Elements

TW Elements is a massive library of more than 500 Bootstrap components recreated using Tailwind CSS. This is a great option for those already familiar with Bootstrap and looking for a modern alternative.

The library boasts better overall design and functionality compared to the original components in the Bootstrap framework, and you can easily search for components by keyword from the home page.

Autocomplete

Autocomplete is an open-source, production-ready JavaScript library for building customizable autocomplete experiences for form inputs and search fields.

You can easily build an autocomplete experience by defining a container, data to populate it, and any virtual DOM solution (JS, React, Vue, Preact, and so on).

CSS Loaders

CSS Loaders is a huge collection of more than 600 CSS loading animations organized under more than 30 categories.

This gallery includes just about any style of loader you can think of, and you can easily copy/paste the HTML/CSS for any loader with just a click.

Flectofy

Flectofy is an interactive tool that provides an interface that allows you to build unique SVG shapes.

The styles of shapes here are pretty niche, so they wouldn’t be useful in too many contexts, but the way the interface works and the look of the shapes are certainly different.

Picyard

Picyard is an app that generates screenshots with attractive backgrounds for use in mockups, social media posts, and so on.

The image/background tool is free, but the app also includes premium features for generating attractive code snippets, charts, mindmaps, timelines, and lots more.

UI Content

UI Content is described as “the best place to find professional placeholder text.” Includes placeholder text under seven different categories and also includes dummy SVG logos.

The idea here is to avoid typical “lorem ipsum” and use actual content instead to ensure your designs look closer to what the final product will be.

Vessel.js

Vessel.js was one of the more unique projects I discovered over the past year. It’s a JavaScript library based on Three.js, the WebGL library, for conceptual ship design, in other words, building boats.

You can check out a number of examples in a gallery, and there’s also a tutorial that gets you up to speed on best practices for using the library — assuming this happens to be your niche!

Modern Font Stacks

Modern Font Stacks is a resource to help you identify the best-performing font stacks. That is, the stacks are based on pre-installed default OS fonts.

You can choose from specific typographic categories like Traditional, Old Style, Neo-Grotesque, Monospace Code, Handwritten, and more. Again, these are generally fonts that are already available on Windows, Mac, Linux, iOS, and Android, giving you the best possible support without extra resource requests.

FancySymbol

FancySymbol is a huge repository of ready-to-copy/paste special characters, text symbols, foreign language symbols, and more.

Includes more than 50 categories of symbols and also allows you to create unique and fancy copy/paste-able text like upside-down text or text written in “invisible ink,” among others.

Observable Plot

Observable Plot is a JavaScript library for creating exploratory data visualizations (i.e., “plots”) using SVG-based charts.

The interface for the plots can include specific features like scales, projections, legends, curves, markers, and more. You’ll have to check out the documentation for the lowdown on these different features, which are illustrated using lots of interactive examples.

Washington Post Design System

The Washington Post Design System is a UI kit specifically built for properties associated with the Washington Post, a popular American daily newspaper and news outlet.

Although it is designed for WaPo’s engineers, it’s MIT-licensed and built-in React using Stitches and Radix UI. So, the customizable components and other assets may be of use if you’re using a similar tech stack.

FormSpamPrevention

FormSpamPrevention isn’t a popular project, but it got quite a bit of traction when I shared it this past year. It offers a simple vanilla JavaScript and HTML solution for preventing form spam.

The script is based on using custom HTML tags for form content that gets converted to valid HTML tags.

Chatbox

Chatbox is a native app for Windows, Mac, and Linux that gives you access to an AI copilot on your desktop.

This particular tool isn’t strictly focused on web development, but it taps into various LLM models and can be used as an overall productivity app for all sorts of daily tech-related tasks.

CSS Generators

CSS Generators is not a single tool but a small collection of CSS generators, a popular kind of tool among front-end developers.

I like this set of generators because it has a few kinds you don’t see elsewhere: Two glow generators (for text and elements) and an underline generator.

Leporello.js

Leporello.js is an interactive functional programming IDE for JavaScript. This means your code is executed instantly as you type, potentially improving debugging processes.

Most of us are likely set on using a particular IDE, but if you’re into experimenting with new ones, this might be a good one to check out.

Calligrapher.ai

Calligrapher.ai is an online tool for AI-generated handwriting samples that you can download as SVG.

There is no need to “write” anything; just type some text and customize stroke width and legibility, and the AI will do the rest. You can choose from 9 different print and cursive styles before generating the sample.

Clone UI

Clone UI is an AI-based tool that lets you generate UI components with a simple text prompt.

The app includes five free daily credits and includes a showcase of existing UI components generated by users.

Float UI

Float UI is a set of 100+ responsive and accessible UI components with RTL support. Also includes five templates.

The components and templates are built with Tailwind and are easy to customize. You can use them with React, Vue, and Svelte, or you can simply use HTML with Tailwind classes.

Calendar.js

Calendar.js is one of numerous date picker and calendar libraries available. This solution is lightweight and has no dependencies.

It’s fully configurable and includes drag-and-drop for events, exporting features, import from iCal and JSON, and lots more.

PCUI

PCUI is yet another React-based component library that makes a list. This one provides a set of pre-styled components.

There’s a storybook that demonstrates all the basic components, and you can also view a few UI examples that show a few advanced examples in action (a to-do list and an example that keeps a “history” of the UI’s state).

Accessible Color Palette Generator

Accessible Color Palette Generator is a great way to ensure any of your designs start with an accessible set of color choices.

You can generate a random accessible palette or enter any color, and the tool will generate an accessible palette for you based on the color you selected.

Picography

Picography is an alternative to the popular Unsplash and similarly offers high-resolution, royalty-free stock photos.

The photos are categorized and searchable and available for free use in commercial projects.

Mailo

Mailo is a component-based, interactive HTML email layout designer that helps you easily build cross-client and responsive HTML emails.

Mailo includes pre-built components and team features, and the components are designed to work with just about any email client.

Pines

Pines is an aptly named UI component library that’s built with Tailwind and Alpine, the popular JavaScript framework that’s similar to a modern version of jQuery.

Pines includes dozens of components, including animations, sliders, tooltips, accordions, modals, and more.

Park UI

Park UI is a set of beautifully designed components built on top of Ark UI, which itself is a set of accessible and customizable components.

Park UI can help you build your own design system, and the home page includes a neat interactive widget that demonstrates how easy it is to style the components. You can use Park UI with React, Vue, Solid, Panda CSS, and Tailwind.

Iconhunt

Iconhunt is an icon search engine that lets you have access to 170,000+ free, open-source icons.

The icons can be downloaded in various formats, including Notion, Figma, SVG, or PNG, and you can customize the color of any icon you choose before downloading.

Sailboat UI

Sailboat UI is a Tailwind-based UI component library that includes 150+ open-source components.

The components are very Bootstrap-esque, and you can search for and see live previews of the components in the docs.

Shaper

Shaper is a generative design tool for UI Interfaces that allows you to visually fiddle with a number of different interface features to customize your own UI.

It includes settings for custom typography, spacing, vertical rhythm, and so on, after which you can copy and paste the design tokens as CSS variables.

Maily

Maily is an open-source editor that makes it easy to create beautiful HTML emails using a set of pre-built components.

It currently includes components in categories covering buttons, variables, text formatting, images, logos, alignment, dividers, spacers, footers, lists, and quotes, with more on the way.

Realtime Colors

Realtime Colors offers an interactive website that lets you test color palettes and typography on real live UI elements in real-time.

You can use the tool to generate palettes and deep links to a specific palette for sharing with others or demoing interfaces in dark or light modes.

Strawberry

Strawberry is described as a “tiny” front-end framework that offers reactivity and composability with zero dependencies, no build step, and less than 3KB gzipped.

The idea here is not to offer a React or Vue alternative but something you’d use for simpler apps and other low-maintenance projects.

Swap.js

Swap.js is a JavaScript micro-library that uses HTML attributes to facilitate Ajax-style navigation in web pages in less than 100 lines of code.

This is in the same vein as libraries like HTMX and Hotwire, allowing you to replace content on the page by sending requests from the server as HTML fragments.

restorePhotos.io

restorePhotos.io is an open-source tool that uses AI to attempt to restore or correct old, blurry, or damaged photos.

You can deploy your own version locally or use their online tool to restore up to 5 photos per day for free.

Better Select

Better Select is a web component that provides a minimal custom select element, something web developers have been grappling with accomplishing for decades!

This solution offers a fallback option and includes a small set of options via attributes that customize the functionality and look.

Space.js

Interestingly, Space.js ended up being the most-clicked tool in my newsletter the past year.

It’s one of two sibling libraries that are based on Three.js. The main one is for creating “future” UIs and panel components, and the other (called Alien.js) is for 3D utilities, materials, shaders, and physics.

What Was Your Favourite Tool of 2023?

That wraps up this year’s roundup of the hottest front-end tools. I’m sure you’ll find at least a few of these to be of use in a new project in the coming months.

As always, I’m always looking for the latest in tools for front-end developers, so feel free to post your favourites from the past year in the comments, and you can subscribe to Web Tools Weekly if you want to keep up with new stuff regularly!

How to Minify JavaScript: A Step-by-Step Guide for Beginner Devs

How to Minify JavaScriptIf you’re a web or app developer looking for ways to improve the performance of your pages, one improvement you’ll want to seriously consider is JavaScript minification. In this post, I’ll show you how to minify JavaScript and what tools you can use to minify JavaScript, depending on your current tech stack.

Top Front-End Tools Of 2022

Over the past 12 months, we continue to see new free and open-source projects shared around the developer community. In my newsletter, Web Tools Weekly, I feature more than two dozen tools every week. As I do every year, I’ve gone through the numbers and put together what were the most popular tools according to my readers.

Some of these tools are interesting in a curious kind of way, but almost all of them are practical tools you can use in your projects today. I’ve listed these in reverse order of popularity based on unique clicks, so the most popular tools are at the bottom. Enjoy!

Related Articles on SmashingMag

WebGi Camera Landing Page

WebGi Camera Landing Page is a landing page template that uses GSAP, ScrollTrigger, and WebGI engine to create beautiful animated, scrollable one-page sites. The example website is impressive! It’s a mock Canon camera website with big graphics and animation.

Due to the potential for performance problems, this is obviously not for every kind of website. But it’s an option to consider if you want something bold and eye-catching.

CSS Fingerprint

Over the past few years, the concept of tracking users via nothing but CSS has been covered a lot. You can search the web for various articles on the topic, but CSS Fingerprint is somewhat of an all-in-one resource on the subject.

You can agree to visit a test page where you can view your own "CSS fingerprint" and the associated GitHub repo has a little more technical info.

PostSrc Tailwind Components

Component libraries are always popular and anything associated with Tailwind tends to do well. PostSrc Tailwind Components includes more than 50 components divided into more than a dozen categories.

Includes components for UI elements like alerts, badges, buttons, breadcrumb navs, cards, CTAs, charts, forms, and more.

Almond.CSS

Almond.CSS is the first of three "class-less" CSS frameworks that made this year’s list. Even with the popularity of utility libraries like Tailwind, it’s interesting to see these kinds of projects do so well.

These libraries work similarly to a CSS reset or normalizer, but are a little more opinionated in terms of applied styles.

Piling.js

Piling.js is a JavaScript library that allows you to build interfaces where large amounts of items can be dragged and dropped into "piles".

It’s built on top of PixiJS, a 2D WebGL renderer and the demos allow you to easily customize the number of items on a page along with a number of other settings and configurations.

Virgo

Virgo is a free HTML template from the folks at CodyHouse. It’s compatible with CodyHouse’s own framework and Tailwind and doesn’t have any third-party dependencies out-of-the-box.

Although it’s described as a "landing page template", it includes six pages and can be used freely in any project with some minor restrictions.

Onion

Onion is a utility based on the most popular article on my personal blog. In that piece, I discuss a potential solution for animating "display: none" to "display:block" in CSS, which isn’t technically possible.

My solution uses a little bit of JavaScript to mimic the effect. This project, built by Parkle Lee, encapsulates the code from that article into an easy-to-use JavaScript utility.

MingCute

I probably come across at least 20 new icon libraries every year. MingCute is one of those and it seemed to gain traction due to its promise of simplicity and the sheer number of available icons.

It currently includes 1,800 icons in SVG or PNG formats and the website allows you to add icons to a live "collection" after which you can download all your selections at once.

Lightning Builder

Lightning Builder is a free website mockup and wireframes builder that includes galleries of common components you can choose from. It requires signing up if you want to save your project and design multiple pages.

The builder boasts hundreds of components that can be customized and the entire experience of the builder’s UI is fairly smooth.

Scroll Btween

Scroll Btween is sort of like a cross between an animation library and a parallax script. It allows you to 'tween' any CSS value for any element on the page relative to its position in the viewport.

There are lots of demos you can try out showing a diverse number of ways you can utilize it in your projects.

Text Cleaner

Text Cleaner is an all-in-one text formatting tool that lets you deal with whitespace and special characters using various settings.

Paste in your text, then choose what you’d like to do — remove leading and trailing space, replace tabs with spaces, convert multiple spaces to single, remove non-ASCII characters, strip emojis, and lots more.

uiverse

uiverse is a repository of community-built HTML and CSS components, free for personal and commercial use.

It currently includes more than 640 components in various categories including buttons, custom checkboxes, toggles, cards, loading animations, and inputs.

Fonoster

Fonoster is an open-source alternative to Twilio, the popular communication API platform.

Fonoster also has its own pricing plan, with a modest free tier, but because it’s open-source, you have the option to host it yourself with no extra cost outside of your own infrastructure.

Zag

Zag is a library of framework-agnostic UI components that currently houses 20+ interactive components including a popover, slider, accordion, combobox, and lots more.

Each of the components can be easily integrated with React, Vue, or Solid.js, with info in the docs on how you can deal with each framework.

Allinone.tools

Allinone.tools is probably one of the largest collections of online utilities that I’ve come across. This includes tools for image manipulation and conversion, PDF tools, various text and list formatting options, CSS and JS minifiers and beautifiers, and lots more.

It also includes tools for carrying out various encryption-related tasks like encoding, decoding, decrypting, and so forth.

Martian Mono

Martian Mono is the only font that made this list, and it’s a nice one. It’s a monospaced version of another font called Martian Grotesk, hence it’s useful for coders.

This one consists of a variable font and 28 styles ranging from condensed to semi-wide and thin to extra-bold.

AnimatiSS

AnimatiSS is a collection of unique CSS animations, similar to other popular animation libraries that allow you to add animations to elements on the page using a class name.

This library includes animations under 10 style categories and you even adjust the duration of each one directly on the page.

HTMLShell

HTMLShell is a simple tool you can use for generating a copy-and-paste customized HTML template for a landing page or other project. The tool includes a number of toggles that allow you to add or remove various elements in the <head> section.

For example, you can include or exclude a CSS reset, Twitter social cards, viewport meta tag, Google Analytics, and lots more.

Formation

Formation is a React and TypeScript-based library of 20+ components that feature accessible features like focus management and color contrast out-of-the-box.

The collection includes buttons, cards, modals, overlays, spinners, toast notifications, tooltips, and lots more.

Vanta.js

Vanta.js is a JavaScript library that produces WebGL-based effects that are cool to look at but should rarely be used, if ever, due to potential performance problems. This tool allows you to create custom animated backgrounds with a few lines of code.

The website allows you to customize different background effects directly on the page using an interactive sidebar, after which you can grab the code.

Kumiko Creator

Kumiko Creator made the list this year probably mostly due to curiosity clicks rather than practicality. This online generator allows you to upload your own photo to convert it to generate customized kumiko patterns.

As the site explains, the term "kumiko" refers to "an ancient Japanese woodworking technique, which involves slotting together many tiny pieces into a lattice."

Atomico

Atomico is a micro-library for creating UI components, similar to projects like React and Vue, with a React-inspired syntax. It’s compatible with those libraries as well as Svelte and Angular.

The library has scored high on performance tests, uses virtual DOM, props, hooks, and more making it an easy solution to transition to if you’re already familiar with other popular solutions.

mmmotif

mmmotif is one of the many useful online generators created by Sébastien Noël. This one allows you to create and customize SVG-based 3D-like isomorphic patterns for use as backgrounds.

The generator allows you to select a base shape for the background, after which you can adjust angle, scale, skew, and the position of the repeated pattern.

DevToys

DevToys is a native offline Windows app that’s a "Swiss army knife" for developers. It includes 20+ tools are useful for various development-related tasks.

There are decoders, encoders, converters, hash generation, text diffing, and much more.

mediaquery.style

mediaquery.style is a simple little online code resource for quickly copying and pasting the most commonly used CSS media query snippets.

The website allows you to grab code for mobile first media queries, range queries, light/dark, reduced-motion, hover/pointer, orientation, and print.

Lyra

Lyra is an open-source, dependency-free, full-featured full-text search engine for your site that can run in any JavaScript runtime including the browser, server, React Native, and more. It’s written in TypeScript and boasts strong performance in comparison to its competitors.

You can try it out directly on the page, which has enabled movie search engine on the page that allows you to search for recent film titles.

W3.CSS

W3.CSS is one of the few tools on this list that isn’t actually new. Apparently it’s been around in some form since 2015 but I only discovered it this past year. It’s a modern, responsive, mobile-first CSS framework similar to Bootstrap, made by the team at W3Schools.

Although W3Schools has received criticism over the years, they remain a popular resource for web developers and everyone seems to love their easy-to-digest documentation. This framework is also well documented and includes 50+ components and various tools and utilities.

Animatize

Animatize is a unique interactive animation builder that allows you to create simple CSS animations by dragging your mouse over a scene on the page.

Upload a background along with a character image, then drag the character over the background to define your animation. The site will generate the CSS code for you using data URIs for the images.

MetaliCSS

MetaliCSS is a JavaScript library that allows you to add a sleek CSS-based metallic look to elements on the page.

After adding the library, use the class metallicss after which you can make any customizations directly in the CSS using three custom properties.

Paper Prototype CSS

Paper Prototype CSS is CSS framework that mimics paper prototyping, sort of like a handdrawn look but a little more ransom-note-ish, with the help of two informal-looking free fonts.

It’s inspired by other hand-drawn CSS frameworks and the home page shows you all the HTML elements in the Paper Prototype style so you can see how they each look.

Ava Maker

Custom avatars always seem to be a popular trend. Ava Maker is an avatar generator that allows you to choose from a variety of styles to build your own custom avatar.

You can customize the hair, skin color, eyebrows, eyes, mouth, clothing, and more, before exporting the SVG or PNG file.

HopeUI

HopeUI is a production-ready open-source admin dashboard based on Bootstrap 5. You can choose a version for Vue, React, Laravel, Tailwind, Figma, and more.

It offers 400+ components, 60+ menu styles, 20+ special plugins, and includes light/dark modes and RTL support.

Amigo CSS

Amigo CSS is described as a "simple, custom-first and intuitive CSS framework" that’s tailored for beginners, building on some of the ideas present in other frameworks.

The framework encourages a custom class (which isn’t required) along with up to a maximum of seven utility classes per element. For the full details, check out the philosophy section of the website.

Hibiki HTML

Hibiki HTML is an HTML-friendly JavaScript framework geared towards all levels of JavaScript developers and doesn’t require any boilerplate setup, scaffolding, build tools, and so on.

The main website includes an interactive tutorial and playground you can use to get accustomed to the syntax. Hibiki’s features are based around the use of the HTML <template> element, with concepts similar to popular libraries like Turbo and Hotwire.

Stylo

Rich text editors that you can embed in a page or app are plenty and Stylo is the one in this category that made this year’s list. It has no dependencies, is framework agnostic, and can be customized to your app’s needs.

Try it out live on the page, it works smoothly and seems to be very user friendly.

CSS.GUI

CSS.GUI is a free visual tool that’s CSS-based, to help you build components that you can export as HTML/CSS code.

You can do just about anything you can do with raw CSS, including adding pseudo-elements, and you also get a tree view of the page’s HTML that allows you to easily select elements before customizing them.

Simple.css

Simple.css is yet another option for a classless CSS framework that provides an attractive starting point for your HTML elements.

Similar to other classless frameworks, this one’s goal is to go beyond merely a reset or normalizer. It makes your elements look good by default without adding any extra bloat associated with larger frameworks.

Reasonable Colors

Reasonable Colors is open-source color system for building color palettes that are both accessible and attractive. This means you get high-contrast combinations that are designer-friendly.

Select a color, after which you can choose your colors from the shades included for each. Choosing accessible colors is possible as long as there is a shade difference of 2 between the selections.

PlainAdmin

PlainAdmin is a Bootstrap 5 admin dashboard template that includes 100+ UI components and 15+ HTML pages.

There’s also a paid version with more components and features but the free version alone is a decent starting point for a solid dashboard template.

Meshy

Meshy is a "mesh" gradient generator that includes a gallery of predefined mesh gradients, along with the ability to customize any of the gradient options. You can also randomize the "meshing" effect for any of the selected gradients, each of which uses 4 colors.

Any of the gradients can be downloaded in PNG format and the file can be sized to up to 3000x3000px for high resolution exports.

Bunny Fonts

Bunny Fonts is a platform of open-source fonts that works as a drop-in replacement for Google Fonts. It has the same API format but with a focus on privacy and being GDPR-friendly.

The site works similarly to the Google Fonts UI and it currently includes over 1,400 fonts, about the same as the number available on Google Fonts.

Stylify

Stylify is a library that generates optimized CSS based on syntax that’s identical to real CSS.

The idea here is that your "classes" are actually CSS property/value pairs, then the library will generate the equivalent styles. This way you don’t have to learn the syntax of the framework, you simply use regular CSS.

Wanda

Wanda is a design system from the team at Wonderflow that includes 40+ components along with a gallery of 360+ vector symbols.

The Wanda system has a focus on accessibility and the concept of form follows function. Both of these contribute to a set of UI components that are usable and accessible to as wide an audience as possible.

Symbols to Copy

Symbols to Copy is a one-stop resource of copy/paste symbols to include in your websites, apps, or documentation.

Includes arrows, currency symbols, fractions, Latin and Greek letters, Math symbols, punctuation and more. I also like that you can click any symbol to get the full code info including Unicode, HTML entity, and more.

Open UI

Open UI isn’t exactly a framework but an industry standard set of guidelines to define how developers can style and extend built-in web UI controls, such as checkboxes, radio buttons, select dropdowns, and so on.

The idea behind the project is to create initiatives that help developers avoid having to reinvent the wheel in the library and framework space, but instead to encourage these components to move to universal standards that everyone can benefit from.

California Design System

The California Design System is a resource for developers and designers building digital products in the state of California, in the U.S.A.

The design system includes principles, style guides, and components with guidelines on use, all for the benefit of filling the needs of customer-facing state websites in California.

Bamboo CSS

Bamboo CSS is yet another option for a classless CSS framework. This one’s source code is written in SCSS and also borrows from a few CSS normalizers.

It includes support for light and dark themes based on user OS settings and includes a small set of CSS variables that you can use for theming, if needed.

IT Tools

IT Tools is another all-in-one resource that includes dozens of tools and utilities useful for web developers and programmers.

This one includes crypto-based tools, conversion tools, miscellaneous web tools, image tools, and text tools. All the tools in this one are well-designed and easy to use.

Qwik

Qwik is described as an "HTML-first" framework with performance at its core due to a small JavaScript footprint and on-demand component loading.

The docs include links to production sites built with the framework that have high page performance scores, demonstrating the real-world benefits.

Siimple

Siimple is a CSS toolkit, or framework, that includes lots of modules, components, and helpers. The components come with a default minimal design that can easily be customized.

The name is based on its simplicity of use by means of official presets and the ability to easily customize colors, fonts, sizes, design accents, and lots more.

Lorem Faces

Lorem Faces is a gallery of free AI-generated photos of people that you can use for mockups and as design placeholders.

You can choose square, rounded, or circular photos and color, greyscale, or sepia for the image’s tone.

HTTP Status Dogs

HTTP Status Dogs is a gallery of HTTP status codes each matched with an appropriate dog photo. You can use these for your own site or apps status messages if you like.

There have been similar projects like this one in the past, but this one includes a few more status codes and many of the matching photos are quite humourous!

Clay.css

Clay.css is a CSS utility for adding a claymorphism style to page elements. This is definitely not going to be used on many projects, but the effect is nice and might come in handy in a children’s project or something else that requires a fun and informal look.

You can include and customize the styles using a utility class, CSS variables, or by means of a Sass mixin.

john-doe

john-doe is a concept for a one-page website that was first put out in late 2020, but I only came across it this past year. The idea behind this one is the use of CSS’s :target pseudo-class, which allows you to display different page content based on hash URLs (e.g. #home, #about, #contact, etc) and IDs on page elements.

The only drawback to this method is the fact that search engines generally don’t recognize hash-based URL changes as separate pages. So this is a novelty-type thing that you probably wouldn’t use on anything important.

Mdash

Mdash is a UI library of components that’s 100% standards-based. The components are all based on HTML and Custom Elements and thus can work along with any web framework.

Many of the components are simply pure HTML with some sensible defaults, while others are a little more interactive depending on the component.

Preline UI

Preline UI is an open-source set of ready-to-use components built on Tailwind CSS. It’s a huge collection of more than 250 components compatible with React and Vue or a plain HTML + Tailwind project.

All components include dark mode and there are base components (buttons, lists, etc.), navigation components, form components, overlays, and tables. All components are beautifully designed and the docs are quite extensive in demonstrating the different ways the components can be used.

UI Buttons

UI Buttons is a unique collection of 100 buttons that feature styles and hover effects you may not have seen elsewhere.

The CSS for each button is easy to grab and you can easily customize the colors and overall look while maintaining the interactive effects.

AgnosticUI

AgnosticUI is a set of framework-agnostic UI components that work in React, Vue, Angular, Svelte, and vanilla JavaScript.

The components allow customization and theming via CSS custom properties and include about 30 common UI patterns along with guidelines for use in the different frameworks or as pure CSS.

TimelineJS

TimelineJS is an open-source JavaScript library and spreadsheet tool that allows you to embed an interactive timeline component on a web page.

You can build the timeline based on data from a Google Sheet template that the site provides, then you can generate the timeline by entering the URL to your sheet. There’s also the option to use JSON as the data source, which would be more privacy-friendly.

JSON Crack

And finally, JSON Crack was the most popular tool of year according to the unique click stats in my newsletter. This was originally referred to as "JSON Visio" and it’s a visualization tool and formatter for your JSON data.

Paste your data into the editor and the tool will display it in an easy-to-read flowchart format that you can customize or even embed on your own pages. There’s a search feature to find data in large files and there’s an associated VS Code extension.

What Was Your Favourite Tool of 2022?

I hope you enjoyed this list of the most popular tools of the past year! While you may not be able to use all of these in your projects today, maybe these will inspire you to build something yourself in 2023. This certainly gives us a good idea of the kinds of things developers today are looking for.

I’m always on the lookout for the latest in tools for front-end developers, so feel free to post your favourites in the comments and you can subscribe to my newsletter if you want to keep up with the latest every week!

Complete Guide to CSS Selector Types (Beginner Friendly)

CSS Selector TypesKnowing the full range of CSS selector types available when writing modern CSS today is crucial to using CSS to the fullest. In the past 10 years or so, the official specification has added a number of different CSS selectors and many of those selectors have strong support across all modern browsers.

Powerful Image Optimization Tools

In recent years, the web development community has rightfully spread the message widely that images are often the largest resource on any given web page. While many developers spend time optimizing other areas of a web page’s performance, reducing the size of images can have a bigger impact on performance than all other areas combined.

You might already know that Smashing Magazine has published the book Image Optimization by Addy Osmani, which covers this topic in full detail. But consider this post a compliment to the book, as this will focus purely on different tools available for reducing the size of images.

WebUtils Bulk Image Compress

WebUtils Bulk Image Compress allows you to compress images and convert them to WebP, JPG, PNG, AVIF, and JXL. There doesn’t seem to be an indication of limitations on file size or the number of files, but it is a slow process if you try to do a bulk conversion. You can also adjust quality and size, and everything is done client-side.

Compressor.io

Compressor.io lets you optimize JPEG, PNG, SVG, GIF, and WebP using lossy or lossless compression up to 10MB per file. If you want to customize the compression or use larger files, you’ll have to get the Premium plan. The compression, in this case, seems to be on the server side, so you’ll get much faster results.

Imagecompresser.com

Imagecompresser.com lets you upload up to 10 files simultaneously and supports PNG, JPEG, WebP, JPG, and GIF formats. There doesn’t seem to be any limit on the file size per image, so this would likely work well for large files of 10 or fewer.

AnyWebP

AnyWebP is specifically for converting images in WebP format, and you can output to JPEG, PNG, or ICO. You can customize by file size or quality. You also have the option to convert just about any file format (TIFF, PSD, BMP, etc.) to WebP. This tool also offers offline native apps for Mac and Windows that let you bulk convert. In any case, none of the files get uploaded to the server.

Compressimage.io

Compressimage.io allows fully offline image optimization with no limits on file size or the number of files. The only limitation this seems to have is that you can only compress JPEG and PNG. The custom options allow you to adjust the compression level, image size, and if you want to convert to WebP. You can also add a custom suffix to the file name.

JPEG.rocks

JPEG.rocks, as the name suggests, is a privacy-friendly JPEG image optimizer, fully client-side and open-source. There doesn’t seem to be a limit to the file size or number of files, and you can customize the output file quality.

Compressor.js

Compressor.js is quite different from the other tools in this list. It includes about a dozen different settings that let you customize the image quality, size, mime type, and more. The only big limitation is that you have to do one file at a time. So this wouldn’t be a good option for bulk resizing but is effective for specific optimizations you want to perform on a particular image.

Squoosh

Squoosh is designed by the Chrome Labs team. The web app is limited to a single image, but it includes several options for reducing size, color palette, choosing a compression method, compression quality level, along with a slew of other advanced settings. The engine that powers this tool is also available as an API or CLI for bulk processing.

SVGOMG

SVGOMG is specifically for reducing the size of SVG graphics. It’s a GUI for SVGO, a Node.js-based tool. SVG optimizers are useful because many programs that produce SVG include redundant and useless info in the SVG code that produces the image.

Optimizilla

Optimizilla uses lossy compression to reduce the size of JPEG, GIF, and PNG images. You can upload up to 20 images, and you have the option to customize the compression level and quality for each of the images before downloading.

Shrink Me

Shrink Me lets you bulk optimize JPEG, PNG, WebP, or SVG images with no discernible quality loss. There is no limit on the number of files or file sizes, but larger files will mean a slower compression process.

JPEG Stripper

JPEG Stripper optimizes JPEG files by stripping out unnecessary data. Allows only a single image uploaded at a time, so this would only be useful for a few images in JPEG format.

Shrink Media

Shrink Media lets you optimize PNG, JPEG, and WebP images up to 5000x5000 resolution, and it’s also available as a mobile app for iOS or Android. Use the interactive sliders to change the quality level and the photo dimensions. You can also paste a URL to an image, but this tool only allows you to optimize one image at a time.

OptimizeImages

OptimizeImages lets you reduce the size of SVG, PNG, JPEG, WebP, GIF, and AVIF while also giving you the option to convert to WebP or AVIF. Optimize up to 30 images and choose a compression quality option (recommended, medium, or ultra).

ImagesTool.com

ImagesTool.com includes a number of different image manipulation tools. You can adjust the size, convert, compress images, and more. Supports JPEG, WebP, SVG, GIF, and APNG. All done client-side, and you can choose between lossless and custom compression. No limit to the number of files you can optimize, and you can also upload by folder or paste in your images.

AVPress

AVPress is a little different as it is specifically for optimizing video files and GIF animations. It allows a single video or GIF to be processed at once and includes several customizations and output settings you can apply to your chosen file.

AVIF Converter

AVIF Converter lets you convert just about any image format to AVIF, a next-generation file format that purports to have better compression than WebP, JPEG, PNG, and GIF. This app doesn’t seem to have any limitations on the number of files or file sizes, but note that the AVIF format is not yet supported in all modern browsers.

TinyPNG

TinyPNG is an older tool that optimizes WebP, PNG, or JPEG files. You can upload up to 20 at a time and up to 5MB in size each.

Build Tools and CLI Tools for Image Optimization

The tools I’ve listed up to this point are good options for manual batch processing or optimizing a few images at a time. But in the context of a large project, you’ll want to consider using different tools that are designed to be incorporated as part of an ongoing workflow or build process. Here are some options you can consider:

  • SVGO is the popular SVG optimization tool that’s the core behind the previously mentioned SVGOMG;
  • libSquoosh is the Squoosh API, allowing you to build JavaScript programs that optimize images on the fly;
  • Squoosh CLI is a command-line tool for using the engine that runs Squoosh;
  • pngquant is a command-line utility specifically for optimizing PNG images;
  • esbuild-squoosh;
  • imagemin is an older unmaintained JavaScript project that lets you optimize images programmatically.

Depending on what build tool or task runner you’re using, the aforementioned imagemin is likely available as a plugin for your tool of choice. Here are some imagemin plugins for different build tools:

Finally, if you’re building native apps that require image processing and optimizing on the fly, here are some C programming language options:

  • MozJPEG is a program for optimizing JPEG images, intended for use as a library in graphics programs, image processing tools, and similar apps;
  • jpegoptim is a utility to optimize JPEG files;
  • libvips is a library for processing images.
Other Tools

You might want to check out other tools and resources for image optimization. These don’t necessarily fall under the above categories, but they might fit one of your specific use cases.

  • QOI
    The Quite OK Image Format is an image format that losslessly compresses images to a similar size to PNG while offering 20x-50x faster encoding and 3x-4x faster decoding.
  • JXL
    Not a tool but a community website centered around the JPEG XL image format.
  • UPNG.js
    This is the PNG engine behind the popular Photopea app, an advanced PNG/APNG decoder and encoder that offers lossy and lossless optimization.
  • Optimus
    A native desktop app that allows you to compress, optimize, and convert images with support for JPEG, PNG, and WebP formats.
  • ImageOptim
    A Mac app and Sketch plugin for reducing image file sizes.
  • pngcrush
    A legacy image compression tool that can be used via the command line.
  • Trimage
    A native cross-platform app and command-line interface to optimize JPEG and PNG images.
  • PNGGauntlet
    An older configurable native app for Windows, Mac, and Linux that optimizes PNG and converts various formats to PNG.
  • Pngyu
    Another native app that uses pngquant for PNG optimization.
Conclusion

If you know of another tool for optimizing different image formats for web, native, or mobile apps, feel free to let us know in the comments. In the meantime, I hope this list of tools will suffice to provide whatever you need to fill your image optimization requirements.

How to Use CSS Media Queries: A Complete Guide for Beginners

how to use CSS media queriesIt’s been more than a decade since responsive web design became a household term, and it’s critical that all front-end developers know how to use CSS media queries in 2022. The basic syntax for a CSS media query isn’t difficult to remember, but it’s not as easy to recall all the different media features you have access to when building responsive websites.

Those HTML Attributes You Never Use

In January, Madison Kanna asked her Twitter followers:

What are the languages/tech you’re excited to learn or learn more deeply this year?

mine: typescript, next.js, react, graphql, solidity, node

— Madison Kanna (@Madisonkanna) January 3, 2022

My answer was easy: HTML. And I wasn’t being sarcastic or mocking in the least. Sure, I pretty much know which tags to use in which instances and how to keep my HTML mostly semantic and accessible.

But there is a whole bunch of lesser-used attributes that I was sure I’d forgotten about, and probably a whole bunch of attributes I didn’t even know existed. This post is the result of my research, and I hope you’ll find some of these useful to you, as you build HTML pages in the coming months.

The enterkeyhint Attribute For Virtual Keyboards

The enterkeyhint attribute is a global attribute that can be applied to form controls or elements that have contenteditable set to true. This attribute assists users on mobile devices that use a virtual on-screen keyboard.

<input type="text" enterkeyhint="done">

enterkeyhint accepts one of seven possible values that will determine what the user sees on his 'enter' key:

  • enter,
  • done,
  • go,
  • next,
  • previous,
  • search,
  • send.

You can see how these “hints” can be useful for the user. Is the user progressing through a series of actions? Are they submitting info? Are they saving a setting? Depending on what they’re doing, you can customize the hint to match your app’s needs.

You can try this one out by visiting the CodePen demo below on a mobile device.

And just to emphasize, this attribute doesn’t accept custom values; the value needs to be one of the seven shown above. An unrecognized value will just default to whatever the device’s default text is for the enter key.

The title Attribute On Stylesheets

This one was brand new to me when doing research for this article and might be the most interesting one in this list. As a bit of background, in case you didn’t know, Firefox has an option that lets you select which style sheet you want to use when viewing a page. Normally, this feature displays two options: “Basic Page Style” and “No Style”, as shown in the image below on my Windows machine.

This lets you quickly test how a page will look when styles are disabled, and it also allows you to view the page with any alternate stylesheets.

The alternate stylesheet feature is enabled with two attributes: The title attribute and rel=alternate applied to a <link> element, as shown in the code below:

<link href="main.css" rel="stylesheet" title="Default">
<link href="contrast.css" rel="alternate stylesheet" title="High Contrast">
<link href="readable.css" rel="alternate stylesheet" title="Readable">

In this case, my “default” styles will apply automatically, but the alternate stylesheets will only apply if I select them using Firefox’s “Page Style” option. You can try out the above example by visiting the following CodePen, using Firefox or another compatible browser:

As mentioned, this feature works in Firefox, but I wasn’t able to get it to work in any Chromium-based browser. MDN’s article on alternate stylesheets says it can be enabled in other browsers using an extension, but I couldn’t find an active extension that does this.

The cite Attribute For The <blockquote> And <q> Elements

I’m sure you use the <blockquote> element pretty regularly. You can use it plainly without an attribute, but you also have the option to use the cite attribute. Here’s an example that quotes the MDN article that describes using cite on <blockquote>:

<blockquote cite="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/blockquote#attr-cite">
      A URL that designates a source document or message for the information quoted. This attribute is intended to point to information explaining the context or the reference for the quote.
</blockquote>

Since my blockquote above is from the MDN article that explains what cite does, I’ve set the URL that points to the page as the cite value.

You can see how this is useful, because it wraps up the quote and the source of the quote in one element. But note this further explanation in the HTML spec:

User agents may allow users to follow such citation links, but they are primarily intended for private use (e.g., by server-side scripts collecting statistics about a site’s use of quotations), not for readers.

And naturally, the same concepts apply to use of cite on the <q> element, which is used for inline quotations.

Attributes For Custom Ordered Lists

Ordered lists using the <ol> element are used often. Some lesser known features that allow you to customize the behaviour of the numbering that appears in such a list are:

  • the reversed attribute, to number the items in reverse order (high to low instead of the default low to high);
  • the start attribute, to define what number to start from;
  • the type attribute, to define whether to use numbers, letters, or Roman numerals;
  • the value attribute, to specify a custom number on a specific list item.

As you can see, ordered lists are a lot more flexible with plain HTML than you might normally be accustomed to.

The reversed attribute is an interesting one, because it doesn’t actually reverse the contents of the list itself; it only reverses the numbers next to each list item.

<ol reversed>
    <li>List item...</li>
    <li>List item...</li>
    <li>List item...</li>
</ol>

The CodePen demo below adds some JavaScript, so you can interactively toggle the reversed attribute.

See the Pen Reverse Ordered Lists with HTML [forked] by Louis Lazaris.

Notice, that the list itself stays the same, but the numbers change. Keep that in mind if you’re looking for a way to reverse the contents. That’s something you would do with JavaScript, CSS, or directly in the HTML source.

Above, I also mentioned three other attributes. Let’s incorporate those into the list to see how they can be used:

<ol reversed start="20" type="1">
    <li>Typee: A Peep at Polynesian Life (1846)</li>
    <li>Omoo: A Narrative of Adventures in the South Seas (1847)</li>
    <li>Mardi: and a Voyage Thither (1849)</li>
    <li>Redburn: His First Voyage (1849)</li>
    <li value="100">White-Jacket; or, The World in a Man-of-War (1850)</li>
    <li>Moby-Dick; or, The Whale (1851)</li>
    <li>Pierre; or, The Ambiguities (1852)</li>
    <li>Isle of the Cross (1853 unpublished, and now lost)</li>
</ol>

Note, the type and start attributes that have been added as well as the value attribute on an individual list item. The type attribute accepts one of the five single-character values (a, A, i, I, 1) representing the numbering type.

Try it using the following interactive demo:

See the Pen Reverse Ordered Lists with start, type, and value Attributes [forked] by Louis Lazaris.

Use the radio buttons to select one of the five values for the type attribute. Then try reversing the list using the Toggle Reversed button. As you can see, there is a ton of possibilities beyond the default behaviour of ordered lists!

The download Attribute For The <a> Element

As ubiquitous as links are on the web, it’s always nice to have an attribute that makes links even more powerful. The download attribute was added to the spec a number of years ago, and it allows you to specify that when a link is clicked, it should be downloaded rather than visited.

<a href="/example.pdf" download>Download File</a>

With no value, the download attribute forces the linked page to be downloaded. Alternatively, you can provide a value which the browser uses as the suggested file name for the downloaded resource.

<a href="/example.pdf" download="my-download.pdf">Download File</a>

As a bonus trick involving this attribute, you can combine this feature with some JavaScript to create a way for the user to download content they create themselves. I covered it a little bit previously in this post, and you can try it out by using the demo below.

See the Pen The download Attribute Combined with a Data URI + JavaScript to Let the User Download Custom HTML [forked] by Louis Lazaris.

The decoding Attribute For The <img> Element

This is another one that was brand new to me when researching this article — and it seems to be fairly new in the spec. Adding the decoding attribute to an image element provides an image decoding hint to the browser.

<img src="/images/example.png" alt="Example" decoding="async">

This attribute is similar to using the async attribute on scripts. The time it takes to load the image doesn’t change, but the manner in which its “decoded” (and thus its content becomes visible in the viewport) is determined by the decoding attribute.

Values are:

  • sync
    Decode the image synchronously, which is generally how browsers do it.
  • async
    Decode the image asynchronously to avoid delaying presentation of other content.
  • auto
    The default which allows the browser to use its own built-in method of decoding.

If you’re curious about the concept of decoding images, the spec has a good explanation that’s not too difficult to follow.

The loading Attribute For The <iframe> Element

As you probably already know, image elements can now include a loading attribute that puts lazy loading into the browser as a feature, something we’ve been doing for years with JavaScript solutions. But don’t forget that the loading attribute can also be used on <iframe> elements:

<iframe src="/page.html" width="300" height="250" loading="lazy">

As with images, the loading attribute accepts either a value of eager (the default browser behaviour) or lazy, which defers loading of the iframe’s contents until the iframe is about to enter the viewport. The only down-side to this attribute is the fact that its use on iframes is not supported in Firefox (though, Firefox does support loading on images).

The form Attribute for Form Fields

In most cases, you’re going to nest your form inputs and controls inside a <form> element. But if your app or layout requires something a little different, you have the option to put a form input anywhere you want and associate it with any <form> element — even one that’s not the element’s parent.

<form id="myForm" action="/form.php">
  <input id="name">
  <button type="submit">
</form>

<input type="email" form="myForm">

As you can see above, the email <input> that’s outside the form has the form attribute set to myForm, which is set to the same value as the id of the form. You can associate a form control (including the submit button) with any form in a document by using this attribute and the form’s id.

You can try this out using this demo page. The form submits using a GET request, so you can see the values submitted in the URL’s query string. On that page, the “comments” box is outside the <form> element.

The only complaint I have with this attribute is that it probably should have been given a more unique name, maybe something like “formowner”. Nonetheless, it’s a useful one to remember, should your design or layout require a parent-less form field.

The cite And datetime Attributes For Deletions/Insertions

I’ve already mentioned cite when dealing with blockquotes, but this attribute can also be used with deletions and insertions marked up with the <del> and <ins> elements. Additionally, both elements can include a datetime attribute.

<del
  cite="https://bugzilla.mozilla.org/show_bug.cgi?id=1620467"
  datetime="2020-07-23"
>Firefox doesn't support CSS's standard <code>appearance</code> property, so you can only use it prefixed.</del>

<ins
cite="https://bugzilla.mozilla.org/show_bug.cgi?id=1620467" datetime="2020-07-23" >The <code>appearance</code> property, previously only available prefixed in Firefox, can now be used in all modern browers unprefixed.</ins>

For each element, here’s what the two attributes represent:

  • cite
    A URL pointing to a resource that explains why the content was deleted or inserted.
  • datetime
    Date that the deletion or insertion was made.

In my case, I’m using the example of some text, describing a CSS property that required a vendor prefix in Firefox. This might be an old blog post. Once the prefixes were removed, I could delete the old text and insert the new text using the <del> and <ins> elements. I can then use the cite attribute to reference the bug report where the problem was resolved.

The label Attribute for the <optgroup> Element

Finally, this last one is a bit of a golden oldie, but because it doesn’t get used too often, maybe you didn’t even know it existed. This one is a combination of an element along with an attribute.

If you have a long list of items included in the options for a <select> drop-down, you can group the options into visible categories using the <optgroup> element along with its associated label attribute:

<select>
  <option>--Your Favourite Animal--</option>
  <optgroup label="Birds">
    <option>Blue Jay</option>
    <option>Cardinal</option>
    <option>Hummingbird</option>
  </optgroup>
  <optgroup label="Sea Creatures">
    <option>Shark</option>
    <option>Clownfish</option>
    <option>Whale</option>
  </optgroup>
  <optgroup label="Mammals">
    <option>Lion</option>
    <option>Squirrel</option>
    <option>Quokka</option>
  </optgroup>
</select>

You can try out an example by using the following CodePen:

See the Pen Using the label Attribute with optgroup Elements [forked] by Louis Lazaris.

Notice, each <optgroup> has a label attribute that defines a heading for each group — but the headings can’t be selected. As a bonus tip, you can also use the disabled attribute on an <optgroup> to disable all the options in that section of the <select> drop-down.

The imagesizes and imagesrcset Attributes for Preloading Responsive Images

This is another pair of attributes that were new to me when researching this article, and both of them are relatively new in the spec as well.

Both of these attributes can be defined along with rel=preload and as on the <link> element, as follows:

<link rel="preload"
      as="image"
      imagesrcset="images/example-480.png 480w,
             images/example-800.png 800w,
             images/example.png 2000w"
     imagesizes="(max-width: 600px) 480px,
            (max-width: 1000px) 800px,
            1000px"
     src="images/example.png"
     alt="Example Image">

Use of rel=preload here informs the browser that we want the indicated resources to load in priority, so they’re not blocked by things like scripts and stylesheets. The as attribute specifies the type of content requested.

You can preload regular images by using the href attribute along with preload and as. But on top of that, you can use the imagesrcset and imagesizes attributes, as I’ve done in the code above.

This allows you to preload the correct image, depending on the size of the viewport or other media features you’ve specified in the imagesizes attribute.

Honorable Mentions

In addition to the attributes I’ve already described and demonstrated in detail, there are some others you might want to look into that I’ll just mention briefly here:

  • The crossorigin attribute which can apply to multiple elements, including <audio>, <img>, <link>, <script>, and <video>, providing support for cross-origin resource sharing (CORS);
  • The title attribute for <dfn> and <abbr>;
  • The new disablepictureinpicture attribute for the <video> element;
  • The integrity attribute for scripts, which helps the browser verify that the resource hasn’t been improperly manipulated;
  • The disabled attribute for the <fieldset> element, to easily disable multiple form elements simultaneously;
  • The multiple attribute for email and file inputs.

If you’ve used any of the attributes mentioned in this article, or if you know of another HTML feature that you’ve personally benefited from using in one of your projects, feel free to let me know in the comments.

Tailwind CSS Tutorial for Beginners: A Guide to Get Started

One of the hottest and admittedly controversial CSS frameworks to land on the front-end scene in recent years is Tailwind CSS, and this Tailwind CSS tutorial for beginners will try to get you up to speed with what it’s all about. I’ll cover the basics, along with why you might want to use a tool like Tailwind CSS to build your web pages, and how Tailwind changes your whole view of HTML and CSS.

Powerful Terminal And Command-Line (CLI) Tools For Modern Web Development

Many modern programmers, including front-end and full-stack developers, work daily with the command line. Even those who are relatively new to web development are picking up command-line skills early and finding practical tools and utilities to enhance their productivity in the terminal.

This post presents a categorized list of many command-line apps I’ve personally discovered over the past few years. Some of them are relatively new, others have been around for a while. So I hope something in this roundup will interest you and help you get stuff done when working in the terminal.

You can jump to a category using the navigation below:

Terminal Apps

This section features terminals, multiplexers, console emulators, mobile terminals, and command-line workspaces that you can use to replace the default terminal app on your system.

tmux

tmux is a popular terminal multiplexer for Unix-like operating systems that lets you easily switch among several programs in a single terminal, with the ability to “detach” a session (while still running in the background) or “reattach” it to a different terminal.

iTerm2

iTerm2, the successor to iTerm, is a replacement for your Terminal on macOS that includes features like split panes, robust search, autocomplete, instant replay, along with a whole slew of configuration options.

Mosh

Mosh is a remote terminal app (or mobile shell) for interactive SSH usage that includes several useful features for those who need to do terminal-based tasks over weak WiFi, cellular networks, or other less-reliable connections.

Zellij

Zellij is a terminal workspace that has the base functionality of a terminal multiplexer (similar to tmux) but includes features that allow users to extend it and create a personalized environment via panes/tabs and plugins.

Hyper

Hyper is an Electron-based terminal app for Mac, Windows, or Linux that’s built with web technologies (HTML/CSS/JS). Includes dozens of themes and plugins and is built on speed and stability.

cmder

cmder is a portable console emulator for Windows that was built due to the lack of a good option in this area for Windows users.

a-Shell

a-Shell is an iOS app that offers a ‘terminal in your pocket’ with files/directory control, compatibility with Apple Shortcuts, multiple windows, and lots more.

Eternal Terminal

Eternal Terminal is another remote terminal app inspired by other similar, popular projects.

Ten Hands

Ten Hands is a terminal app for Mac, Linux, and Windows that is billed as the simplest way to organize and run command-line tasks, useful for those who run similar daily tasks on multiple projects.

eDEX-UI

eDEX-UI is a fullscreen, cross-platform terminal emulator and system monitor heavily inspired by science fiction movie UIs, in particular, the Tron: Legacy film.

Tabby

Tabby, formerly “Terminus”, is a customizable cross-platform terminal app for local shells, SSH, serial, and Telnet connections that includes support for features like split panes, smart tabs, customizable hotkeys, and lots more.

Fish Shell

Fish Shell is another option for a command-line shell for Linux, macOS, and Windows that includes auto-suggest, tab completions, 24-bit color, web-based configuration, syntax highlighting, among other practical features.

Terminal Utilities And Enhancements

Once you’ve got your primary workspace, you’ll want to enhance it with various tools, utilities, themes, and so forth. This section includes some useful tools to make your terminal experience more enjoyable.

Oh My Zsh

Oh My Zsh is an open-source, community-driven framework for managing your configuration for Z Shell (or Zsh, a popular Unix shell). It comes bundled with thousands of helpful functions, helpers, 300+ plugins, 140+ themes, and more. Works best on macOS or Linux, but can also be used on Windows using something like Cygwin or WSL2.

Fig

Fig adds VSCode-style autocomplete to your existing terminal and includes support for existing CLI tools like Git, npm, Kubernetes, Docker, AWS, Google Cloud, and more.

fzf

fzf is a fast, portable, fuzzy finder for the command line that lets you run fuzzy search queries with a comprehensive feature set.

Shell History

Shell History (not free) is a macOS app that integrates with Bash, Zsh, or Fish and allows you to easily backup and sync via iCloud and organize your shell history in “notebooks”.

htop

htop is an interactive process viewer, originally Linux-only but now cross-platform, that aims to improve on the Linux top command by providing extra features when viewing running processes.

GitHub CLI

GitHub CLI, in case you missed it, is the official cross-platform command-line interface for GitHub, bringing pull requests, issues, and other GitHub-related tasks to your terminal.

Streamhut

Streamhut lets you share your terminal in real-time without installing anything. Simply run one of two commands (depending on your setup), useful for live terminal sessions in team collabs, interviews, or teaching.

icdiff

icdiff is a terminal-based file diff tool that makes good use of colors to present diffs in a more practical, visual manner.

>\_TerminalSplash

TerminalSplash, as the name suggests, is like Unsplash, but for terminal themes. Choose from more than 200 user-submitted themes or submit your own.

Terminalizer

Terminalizer is a customizable and cross-platform terminal recorder that lets you record terminal sessions then share them as animated GIFs or via a web player.

Asciinema

Asciinema is another popular option for terminal recording and sharing, but not available for Windows. The cool thing about this one is that the recorded output is not a video but a plain text animation of the terminal session, meaning you can select and copy/paste items from recordings.

gtop

gtop is another enhancement on the top command that provides a system monitoring dashboard for your terminal. Require Node.js and includes partial support on Windows.

DevDash

DevDash is a highly configurable terminal dashboard for developers and creators. You can customize it to display information from sources like Google Analytics, GitHub, Feedly, shell command output, and more.

Honorable mentions:

  • ora
    An elegant terminal spinner.
  • tiny-care-terminal
    A little dashboard that tries to take care of you when you’re using your terminal.
  • theme.sh
    A shell script that lets you set your terminal theme that includes 270+ preloaded themes.
Command-Line Scripting And Frameworks

Some numerous libraries and frameworks allow you to build and maintain your own command-line apps and utilities. Below you’ll find a few of those for Bash, JavaScript, and more.

Command And Conquer (cac)

Command And Conquer, also called cac, is a lightweight JavaScript framework for building command-line apps. For example, it’s been used to build several Node.js-based scaffolding tools.

zx

zx is a popular alternative to Bash from engineers at Google that allows you to write command-line apps using JavaScript with an easy-to-use API that allows you to call executables and get their output, handle errors, and more.

present

present is a Markdown-based presentation tool for the terminal that includes colors and effects and allows you to play pre-recorded playable code blocks as slides.

Bach

Bach is a Bash testing framework that can be used to test scripts that contain dangerous commands like rm -rf / and also includes APIs (e.g. @mock, @ignore, @mockallto, etc.) to mock commands.

CLUI

CLUI is a JavaScript API with utilities to allow you to build command-line interfaces with context-aware autocomplete into your apps (i.e. terminal-like applications that users interact with).

ShellCheck

ShellCheck is a shell extension to help you find bugs in your shell scripts.

Honorable Mentions

  • Bashō
    Lets you write complex shell tasks using plain JavaScript and it mixes well with shell commands and scripts.
  • import
    A fast and easy-to-use module system for Bash and other Unix shells.
  • Bash Infinity
    A modular and lightweight library and boilerplate framework for writing tools using Bash.
Productivity Tools For The Terminal

Finally, this category puts together a small sampling of command-line utilities and programs that help with various productivity-related tasks like keeping stuff organized, sharing files, and more.

Dash Dash

Dash Dash is an online documentation site that presents the Unix man pages (i.e. manual pages) in a more palatable format, to help those less familiar with the terminal learn to use the command line.

nb

nb is a command-line tool with features that include local web note‑taking, bookmarking, archiving, and encryption. Storage is in plain text, includes Git-based versioning, wiki-style linking, color themes, and lots more.

Rclone

Rclone is an open-source command-line program that allows you to manage files on 40+ cloud storage services (Amazon S3, Dropbox, Google Drive, Azure, etc.). It includes cloud equivalents for familiar Unix commands and other features.

navi

navi is an interactive cheatsheet tool for your terminal. In addition to other features, you can browse through cheatsheet repositories, import cheatsheets, or add your own.

Taskbook

Taskbook is a fast command-line tool that lets you organize tasks, boards, and notes in your terminal, with features like search/filter, custom storage location, and a simple and user-friendly syntax.

Project Explorer

Project Explorer is a CLI tool that lets you build a tree visualization of any project. This would come in handy when bringing on new team members or when inheriting a new project.

transfer.sh

transfer.sh is a fast and easy-to-use app for sharing files via the command line. Includes support for services like Amazon S3, Google Drive, Storj, and the local file system.

Honorable Mentions

  • ack
    A code-searching tool, similar to grep but optimized for programmers searching large trees of source code.
  • goto
    A shell utility with auto-complete support to navigate to aliased directories.
  • bashupload
    Upload files (up to 50GB) via the command line to easily share between servers, desktops, and mobile devices.
  • copyfiles
    A command-line utility that adds extra features to copying files in your terminal.
What’s Your Favourite Command-Line Tool?

As mentioned, this wasn’t meant to be an exhaustive list, but merely a big collection of relevant command-line apps and utilities that I’ve personally come across in the past few years.

If you’ve built something yourself or if there’s one you use regularly that supercharges your terminal experience, feel free to drop it in the comments!

The Ultimate CSS Grid Tutorial for Beginners (With Interactive Examples)

For some time, many CSS developers had been holding off on incorporating the CSS Grid Layout specification in real projects. This was due to either volatility of the spec, lack of browser support, or possibly not having the time to invest in learning a new layout technique. We're now at the stage that Grid Layout is safe to use in most projects, so I hope this CSS Grid Layout tutorial will help if you haven't yet fully examined this CSS feature.

15+ Front-End Tools You Should Know About: My Favorite Finds for 2020

In this post, I’m going to round up (with some screenshots and demos) some of the most interesting front-end tools I’ve found that I think you’ll find useful in 2020. These aren’t necessarily the most popular tools or the hottest tools, but I think each of them is unique in their use case and deserve a little more attention. These are essentially my favorite finds of the year in front-end tools.

Getting To Know The MutationObserver API

Getting To Know The MutationObserver API

Getting To Know The MutationObserver API

Louis Lazaris

In complex web apps, DOM changes can be frequent. As a result, there are instances where your app might need to respond to a specific change to the DOM.

For some time, the accepted way to look for changes to the DOM was by means of a feature called Mutation Events, which is now deprecated. The W3C-approved replacement for Mutation Events is the MutationObserver API, which is what I’ll be discussing in detail in this article.

A number of older articles and references discuss why the old feature was replaced, so I won’t go into detail on that here (besides the fact that I wouldn’t be able to do it justice). The MutationObserver API has near complete browser support, so we can use it safely in most — if not all — projects, should the need arise.

Basic Syntax For A MutationObserver

A MutationObserver can be used in a number of different ways, which I’ll cover in detail in the rest of this article, but the basic syntax for a MutationObserver looks like this:

let observer = new MutationObserver(callback);
    
function callback (mutations) {
  // do something here
}

observer.observe(targetNode, observerOptions);

The first line creates a new MutationObserver using the MutationObserver() constructor. The argument passed into the constructor is a callback function that will be called on each DOM change that qualifies.

The way to determine what qualifies for a particular observer is by means of the final line in the above code. On that line, I’m using the observe() method of the MutationObserver to begin observing. You can compare this to something like addEventListener(). As soon as you attach a listener, the page will ‘listen’ for the specified event. Similarly, when you start observing, the page will begin ‘observing’ for the specified MutationObserver.

The observe() method takes two arguments: The target, which should be the node or node tree on which to observe for changes; and an options object, which is a MutationObserverInit object that allows you to define the configuration for the observer.

The final key basic feature of a MutationObserver is the disconnect() method. This allows you to stop observing for the specified changes, and it looks like this:

observer.disconnect();

Options To Configure A MutationObserver

As mentioned, the observe() method of a MutationObserver requires a second argument that specifies the options to describe the MutationObserver. Here’s how the options object would look with all possible property/value pairs included:

let options = {
  childList: true,
  attributes: true,
  characterData: false,
  subtree: false,
  attributeFilter: ['one', 'two'],
  attributeOldValue: false,
  characterDataOldValue: false
};

When setting up the MutationObserver options, it’s not necessary to include all these lines. I’m including these simply for reference purposes, so you can see what options are available and what types of values they can take. As you can see, all except one are Boolean.

In order for a MutationObserver to work, at least one of childList, attributes, or characterData needs to be set to true, otherwise an error will be thrown. The other four properties work in conjunction with one of those three (more on this later).

So far I’ve merely glossed over the syntax to give you an overview. The best way to consider how each of these features works is by providing code examples and live demos that incorporate the different options. So that’s what I’ll do for the rest of this article.

Observing Changes To Child Elements Using childList

The first and simplest MutationObserver you can initiate is one that looks for child nodes of a specified node (usually an element) to be added or removed. For my example, I’m going to create an unordered list in my HTML, and I want to know whenever a child node is added or removed from this list element.

The HTML for the list looks like this:

<ul id="myList" class="list">
  <li>Apples</li>
  <li>Oranges</li>
  <li>Bananas</li>
  <li class="child">Peaches</li>
</ul>

The JavaScript for my MutationObserver includes the following:

let mList = document.getElementById('myList'),
options = {
  childList: true
},
observer = new MutationObserver(mCallback);

function mCallback(mutations) {
  for (let mutation of mutations) {
    if (mutation.type === 'childList') {
      console.log('Mutation Detected: A child node has been added or removed.');
    }
  }
}

observer.observe(mList, options);

This is only part of the code. For brevity, I’m showing the most important sections that deal with the MutationObserver API itself.

Notice how I’m looping through the mutations argument, which is a MutationRecord object that has a number of different properties. In this case, I’m reading the type property and logging a message indicating that the browser has detected a mutation that qualifies. Also, notice how I’m passing the mList element (a reference to my HTML list) as the targeted element (i.e. the element on which I want to observe for changes).

Use the buttons to start and stop the MutationObserver. The log messages help clarify what’s happening. Comments in the code also provide some explanation.

Note a few important points here:

  • The callback function (which I’ve named mCallback, to illustrate that you can name it whatever you want) will fire each time a successful mutation is detected and after the observe() method is executed.
  • In my example, the only ‘type’ of mutation that qualifies is childList, so it makes sense to look for this one when looping through the MutationRecord. Looking for any other type in this instance would do nothing (the other types will be used in subsequent demos).
  • Using childList, I can add or remove a text node from the targeted element and this too would qualify. So it doesn’t have to be an element that’s added or removed.
  • In this example, only immediate child nodes will qualify. Later in the article, I’ll show you how this can apply to all child nodes, grandchildren, and so on.

Observing For Changes To An Element’s Attributes

Another common type of mutation that you might want to track is when an attribute on a specified element changes. In the next interactive demo, I’m going to observe for changes to attributes on a paragraph element.

let mPar = document.getElementById('myParagraph'),
  options = {
    attributes: true
  },
  observer = new MutationObserver(mCallback);

function mCallback (mutations) {
  for (let mutation of mutations) {
    if (mutation.type === 'attributes') {
      // Do something here...
    }
  }
}

observer.observe(mPar, options);

Again, I’ve abbreviated the code for clarity, but the important parts are:

  • The options object is using the attributes property, set to true to tell the MutationObserver that I want to look for changes to the targeted element’s attributes.
  • The mutation type I’m testing for in my loop is attributes, the only one that qualifies in this case.
  • I’m also using the attributeName property of the mutation object, which allows me to find out which attribute was changed.
  • When I trigger the observer, I’m passing in the paragraph element by reference, along with the options.

In this example, a button is used to toggle a class name on the targeted HTML element. The callback function in the mutation observer is triggered every time the class is added or removed.

Observing For Character Data Changes

Another change you might want to look for in your app is mutations to character data; that is, changes to a specific text node. This is done by setting the characterData property to true in the options object. Here’s the code:

let options = {
    characterData: true
  },
  observer = new MutationObserver(mCallback);
  
function mCallback(mutations) {
  for (let mutation of mutations) {
    if (mutation.type === 'characterData') {
      // Do something here...
    }
  }
}

Notice again the type being looked for in the callback function is characterData.

In this example, I’m looking for changes to a specific text node, which I target via element.childNodes[0]. This is a little hacky but it will do for this example. The text is user-editable via the contenteditable attribute on a paragraph element.

Challenges When Observing For Character Data Changes

If you’ve fiddled around with contenteditable, then you might be aware that there are keyboard shortcuts that allow for rich text editing. For example, CTRL-B makes text bold, CTRL-I makes text italic, and so forth. This will break up the text node into multiple text nodes, so you’ll notice the MutationObserver will stop responding unless you edit the text that’s still considered part of the original node.

I should also point out that if you delete all the text, the MutationObserver will no longer trigger the callback. I’m assuming this happens because once the text node disappears, the target element is no longer in existence. To combat this, my demo stops observing when the text is removed, although things do get a little sticky when you use rich text shortcuts.

But don’t worry, later in this article, I’ll discuss a better way to use the characterData option without having to deal with as many of these quirks.

Observing For Changes To Specified Attributes

Earlier I showed you how to observe for changes to attributes on a specified element. In that case, although the demo triggers a class name change, I could have changed any attribute on the specified element. But what if I want to observe changes to one or more specific attributes while ignoring the others?

I can do that using the optional attributeFilter property in the option object. Here’s an example:

let options = {
      attributes: true,
      attributeFilter: ['hidden', 'contenteditable', 'data-par']
    },
    observer = new MutationObserver(mCallback);

function mCallback (mutations) {
  for (let mutation of mutations) {
    if (mutation.type === 'attributes') {
      // Do something here...
    }
  }
}

As shown above, the attributeFilter property accepts an array of specific attributes that I want to monitor. In this example, the MutationObserver will trigger the callback each time one or more of the hidden, contenteditable, or data-par attributes is modified.

Again I’m targeting a specific paragraph element. Notice the select drop down that chooses which attribute will be changed. The draggable attribute is the only one that won’t qualify since I didn’t specify that one in my options.

Notice in the code that I’m again using the attributeName property of the MutationRecord object to log which attribute was changed. And of course, as with the other demos, the MutationObserver won’t start monitoring for changes until the “start” button is clicked.

One other thing I should point out here is that I don’t need to set the attributes value to true in this case; it’s implied due to attributesFilter being set to true. That’s why my options object could look as follows, and it would work the same:

let options = {
  attributeFilter: ['hidden', 'contenteditable', 'data-par']
}

On the other hand, if I explicitly set attributes to false along with an attributeFilter array, it wouldn’t work because the false value would take precedence and the filter option would be ignored.

Observing For Changes To Nodes And Their Sub-Tree

So far when setting up each MutationObserver, I’ve only been dealing with the targeted element itself and, in the case of childList, the element’s immediate children. But there certainly could be a case where I might want to observe for changes to one of the following:

  • An element and all its child elements;
  • One or more attributes on an element and on its child elements;
  • All text nodes inside an element.

All of the above can be achieved using the subtree property of the options object.

childList With subtree

First, let’s look for changes to an element’s child nodes, even if they’re not immediate children. I can alter my options object to look like this:

options = {
  childList: true,
  subtree: true
}

Everything else in the code is more or less the same as the previous childList example, along with some extra markup and buttons.

Here there are two lists, one nested inside the other. When the MutationObserver is started, the callback will trigger for changes to either list. But if I were to change the subtree property back to false (the default when it’s not present), the callback would not execute when the nested list is modified.

Attributes With subtree

Here’s another example, this time using subtree with attributes and attributeFilter. This allows me to observe for changes to attributes not only on the target element but also on the attributes of any child elements of the target element:

options = {
  attributes: true,
  attributeFilter: ['hidden', 'contenteditable', 'data-par'],
  subtree: true
}

This is similar to the previous attributes demo, but this time I’ve set up two different select elements. The first one modifies attributes on the targeted paragraph element while the other one modifies attributes on a child element inside the paragraph.

Again, if you were to set the subtree option back to false (or remove it), the second toggle button would not trigger the MutationObserver callback. And, of course, I could omit attributeFilter altogether, and the MutationObserver would look for changes to any attributes in the subtree rather than the specified ones.

characterData With subtree

Remember in the earlier characterData demo, there were some problems with the targeted node disappearing and then the MutationObserver no longer working. While there are ways to get around that, it’s easier to target an element directly rather than a text node, then use the subtree property to specify that I want all the character data inside that element, no matter how deeply nested it is, to trigger the MutationObserver callback.

My options in this case would look like this:

options = {
  characterData: true,
  subtree: true
}

After you start the observer, try using CTRL-B and CTRL-I to format the editable text. You’ll notice this works much more effectively than the previous characterData example. In this case, the broken up child nodes don’t affect the observer because we’re observing all nodes inside the targeted node, instead of a single text node.

Recording Old Values

Often when observing for changes to the DOM, you’ll want to take note of the old values and possibly store them or use them elsewhere. This can be done using a few different properties in the options object.

attributeOldValue

First, let’s try logging out the old attribute value after it’s changed. Here’s how my options will look along with my callback:

options = {
  attributes: true,
  attributeOldValue: true
}

function mCallback (mutations) {
  for (let mutation of mutations) {
    if (mutation.type === 'attributes') {
      // Do something here...
    }
  }
}

Notice the use of the attributeName and oldValue properties of the MutationRecord object. Try the demo by entering different values in the text field. Notice how the log updates to reflect the previous value that was stored.

characterDataOldValue

Similarly, here’s how my options would look if I want to log old character data:

options = {
  characterData: true,
  subtree: true,
  characterDataOldValue: true
}

Notice the log messages indicate the previous value. Things do get a little wonky when you add HTML via rich text commands to the mix. I’m not sure what the correct behavior is supposed to be in that case but it is more straightforward if the only thing inside the element is a single text node.

Intercepting Mutations Using takeRecords()

Another method of the MutationObserver object that I haven’t mentioned yet is takeRecords(). This method allows you to more or less intercept the mutations that are detected before they are processed by the callback function.

I can use this feature using a line like this:

let myRecords = observer.takeRecords();

This stores a list of the DOM changes in the specified variable. In my demo, I’m executing this command as soon as the button that modifies the DOM is clicked. Notice that the start and add/remove buttons don’t log anything. This is because, as mentioned, I’m intercepting the DOM changes before they are processed by the callback.

Notice, however, what I’m doing in the event listener that stops the observer:

btnStop.addEventListener('click', function () {
  observer.disconnect();
  if (myRecords) {
    console.log(`${myRecords[0].target} was changed using the ${myRecords[0].type} option.`);
  }
}, false);

As you can see, after stopping the observer using observer.disconnect(), I’m accessing the mutation record that was intercepted and I’m logging the target element as well as the type of mutation that was recorded. If I had been observing for multiple types of changes then the stored record would have more than one item in it, each with its own type.

When a mutation record is intercepted in this way by calling takeRecords(), the queue of mutations that would normally be sent to the callback function is emptied. So if for some reason you need to intercept these records before they’re processed, takeRecords() would come in handy.

Observing For Multiple Changes Using A Single Observer

Note that if I’m looking for mutations on two different nodes on the page, I can do so using the same observer. This means after I call the constructor, I can execute the observe() method for as many elements as I want.

Thus, after this line:

observer = new MutationObserver(mCallback);

I can then have multiple observe() calls with different elements as the first argument:

observer.observe(mList, options);
observer.observe(mList2, options);

Start the observer, then try the add/remove buttons for both lists. The only catch here is that if you hit one of the “stop” buttons, the observer will stop observing for both lists, not just the one it’s targeting.

Moving A Node Tree That’s Being Observed

One last thing I’ll point out is that a MutationObserver will continue to observe for changes to a specified node even after that node has been removed from its parent element.

For example, try out the following demo:

This is another example that uses childList to monitor for changes to the child elements of a target element. Notice the button that disconnects the sub-list, which is the one being observed. Click the “Start…” button, then click the “Move…” button to move the nested list. Even after the list is removed from its parent, the MutationObserver continues to observe for the specified changes. Not a major surprise that this happens, but it’s something to keep in mind.

Conclusion

That covers just about all the primary features of the MutationObserver API. I hope this deep dive has been useful for you to get familiar with this standard. As mentioned, browser support is strong and you can read more about this API on MDN’s pages.

I’ve put all the demos for this article into a CodePen collection, should you want to have an easy place to mess around with the demos.

Smashing Editorial (dm, il)