Jonathan Bennett

Upgrade Your Tailwind Setup for JS States

Ever wondered how to seamlessly toggle features based on JavaScript availability? Here’s a simple way to ensure your app looks great whether JavaScript is enabled or not.

This method lets you work with CSS variants just like hover: and lg: — in only three steps.


Step 1: Add a no-js Fallback Class

Ensure a no-js class is always present on your <body> tag. If JavaScript fails to load, the class will remain intact.

<body class="no-js">
</body>

Step 2: Enable JS Detection with a Script

Add this snippet to your application.js file to toggle the presence of JavaScript:

document.addEventListener("turbo:load", () => {
  document.body.classList.remove("no-js")
  document.body.classList.add("js")
})

Step 3: Extend Tailwind for JS and No-JS States

Use Tailwind’s plugin system to create custom variants for js and no-js:

const plugin = require("tailwindcss/plugin");

module.exports = {
  plugins: [
	plugin(({ addVariant }) => {
	  addVariant("js", "body.js &");
	  addVariant("no-js", "body.no-js &");
	}),
  ],
};

Example Usage

Now you can toggle elements based on JavaScript presence:

<%= link_to "Cool JS Feature", "#", class: "no-js:hidden" %>
<%= link_to "Plain Feature", "#", class: "js:hidden" %>

With just a few lines of code, you can provide an elegant fallback for users and easily manage JavaScript-dependent features.

Give it a try and let me know how it works for you!