Pan Zhan

CSS Injection in JSDOM

Tailwind CSS is a popular CSS framework that provides utility classes to style web applications. However, when it comes to unit testing with JSDOM, injecting the stylesheet can be a tricky task. In this blog post, we will explore a common issue that developers face when trying to inject Tailwind CSS stylesheets into JSDOM for unit testing purposes and how to solve it.

A furious man yelling at the computer

Introduction

When unit testing React components with React Testing Library, developers need to make sure that the component is visible in certain scenarios. This visibility is often controlled by the "hidden" class from Tailwind CSS. However, without injecting the stylesheet into the DOM, class names are meaningless. In this blog post, we will explore a solution to a problem encountered unexpectedly.

Stylesheet Injection to JSDom

Here is a piece of code that's commonly introduced to the customRender function when using React Testing Library

// inject the style sheet generated by tailwind into document before rendering
const style = document.createElement("style");
const cssText = fs.readFileSync("./lib/src/index.css", "utf8");
style.innerHTML = cssText;
document.head.appendChild(style);

Problem

When trying to append a "style" element to the "head" of the document and add the styles as its content, JSDOM throws an error that says "Error: Could not parse CSS stylesheet." After some research, we figured out that JSDOM uses CSSOM as its underlying CSS parser. So, we tried to parse it ourselves by installing the CSSOM as a dependency and running cssom.parse([loadedFile]). However, we encountered an error that pointed to a chunk of CSS generated by Tailwind:

.after\:content-\[\"\"\]::after {
  --tw-content: "";
  content: var(--tw-content);
}

The error message complained about an unmatched " in the classname .after\:content-\[\"\"\]::after. This classname came from a Tailwind utility after:content-[""].

Root Cause

The classname .after\:content-\[\"\"\]::after contains \", which cannot be parsed by CSSOM. As a result, the stylesheet injection fails.

Solution

The solution is to omit the after:content-[""] utility. This utility is not needed because Tailwind will automatically add content: '' by default when using ::before and ::after modifiers. Developers only need to specify a different value if they want to. This information can be found in the official Tailwind documentation (open with chrome).

Conclusion

Unit testing with JSDOM and Tailwind CSS can be challenging, but with the right knowledge, developers can overcome common issues. In this blog post, we explored a solution to a common problem that developers face when injecting Tailwind CSS stylesheets into JSDOM for unit testing purposes. Remember to always refer to official documentation and stay up-to-date with the latest best practices.

This article is co-authored with ChatGPT

Cover image generated by Midjourney

No comments yet

All rights reserved © Pan Zhan 2025