When building a website with Webflow, I end up using "custom code" for more things than I initially expect. I use it to implement features Webflow doesn’t support natively, such as Dark mode, interactions that require specific conditions, and even something as simple as setting an SVG icon’s color to "currentColor".
Personally, I prefer using Code Embeds as reusable components rather than writing custom code at the page level. As I kept filling the gaps in Webflow with custom code, I started wondering: Could I build a simple JavaScript-based tool directly in Webflow?
There was one small task I had already been relying on ChatGPT for whenever I needed it. The logic itself wasn’t particularly complicated, but building a dedicated tool for it had always felt like more work than it was worth. So when I decided to experiment with building a tool in Webflow, it seemed like a good place to start.
Color Fitting
First, a quick explanation of the task I wanted to turn into a tool.
When I create color palettes for the foundation of my design system, I go through several stages of adjustment. I first create a grayscale palette that defines the brightness steps for all other palettes, then generate palettes for individual hues based on the LCH color space. I work with the generated colors as HSB values, slightly adjusting H, S, and B so that each palette matches the relative luminance values of the grayscale palette.
There are a few more steps involved, including adjustments to alpha values, but at the very end, I perform curve fitting so that the manually adjusted color values follow a consistent progression rather than an irregular one. Manual adjustments can bring each individual color close to the intended result, both visually and numerically. But because each value is adjusted independently and somewhat heuristically, the progression of those values across the palette can become irregular. To smooth out those inconsistencies, I find a cubic curve that follows the overall distribution of the palette and adjust the individual color values to fit that curve.
Color Fitting is a small tool I built to handle this final curve-fitting step.
Process
I’m not a developer, so I rely heavily on Claude for the coding side of my projects. Most of the tools I build are Figma plugins. My usual process is to first write a specification based on the structure I have in mind, then have Claude draft the initial code for the logic and UI. For the UI, I’ve found it less frustrating to let Claude come up with a rough implementation based on the structure I describe, then take that structure and rework it to match what I actually want, rather than trying to get Claude to precisely reproduce a design I’ve already made. I can then take that result apart and redesign it myself. Once Claude generates the initial UI, I bring the HTML into Figma and modify it to match the interface I actually want.
This time, however, I was building the tool in Webflow rather than as a Figma plugin, so the process had to change. Instead of modifying Claude’s HTML and CSS directly, I had to recreate its HTML structure in Webflow and define the necessary Style Selectors through the Webflow UI. Unlike a Figma plugin, which operates at a fixed width, a web-based tool needs to work across a wide range of viewport widths. After rebuilding the interface in Webflow, I had to spend additional time making it responsive.
The core logic still runs as custom code, so that part has little to do with Webflow itself. But anything that connects the logic to the interface does. Adding a new row, reading user input, or displaying calculated results all depend on the actual DOM structure created in Webflow. That meant the code Claude initially generated had to be modified again to match the final Webflow DOM.
I also added a few features along the way that I hadn’t considered initially but found necessary after actually using the tool. Eventually, that became the finished version of Color Fitting.
Challenges
1. Building the UI structure for a tool
The first challenge was creating all the Style Selectors the tool needed and using them to build the actual DOM structure. I already have a personal design system and component library in Figma. My Webflow site, however, was originally built as a portfolio and blog for showcasing and documenting my work. It didn’t have the range of product-level Style Selectors I needed for a tool like this. Creating all of them from scratch and then building the entire interface in Webflow was not a small task.
I could have turned each repeating row into a Webflow Component, but I didn’t want to create components specifically for elements that would only exist on a single page and never be reused elsewhere on the site. There was a trade-off, of course. Whenever I needed to change something in the row structure, I had to apply the same change to every row individually.
2. Handling different viewport widths
The second challenge was responsive design. Unlike a Figma plugin with a fixed width, a web page can be viewed at many different browser widths. Webflow’s built-in Breakpoints cover the typical device-based responsive cases, but Color Fitting has a much higher information density than a typical page. The UI needed additional adjustments at many specific viewport widths. Each row needs to display several different values at the same time. I wanted to preserve as much of that information as possible without letting the interface become visually cluttered.
To do that, I repeatedly resized the viewport after implementing the page in Webflow, identified the widths where the UI started to break, and adjusted specific Style Selectors at those points. Many of those points fell outside the Breakpoints Webflow provides by default, so I had to add extra Media Queries through custom CSS.
3. Implementing elements Webflow only partially supports
The third challenge involved elements that Webflow either doesn’t provide directly or expects to be used in a particular context. Input fields and checkboxes were the main examples. Webflow expects these elements to be used as part of a Form, but I needed them as independent parts of the tool. I therefore had to write the actual HTML inside Code Embeds and create separate master elements so I could manage their Style Selectors through Webflow.
Code Embed also becomes part of the DOM itself, which means the actual input ends up nested inside it. This became a problem when an interaction on an input needed to affect another element, or vice versa. Elements that were conceptually siblings in my intended UI structure were no longer siblings in the actual DOM because the Code Embed sat between them. As a result, some of the CSS needed to handle those interactions became more complicated than I had originally expected.
4. Adapting the initial code to the actual DOM
The final challenge was essentially the result of the previous three. The HTML structure Claude assumed when generating the initial UI was different from the DOM I eventually built in Webflow. As a result, the code connecting the logic to the UI didn’t work when I simply dropped it into the page. Anything that depended on the DOM had to be adjusted: adding and removing rows, reading and updating input values, and displaying calculated results in the appropriate elements.
Whenever I tried to modify too much of this myself, the code tended to go further off track. So I gave Claude the URL of the actual page, asked it to inspect the DOM, and told it to adjust the code accordingly — basically, to figure it out on its own. Unsurprisingly, my tokens melted away pretty quickly.
Would I do it again?
Probably, under the right conditions.
If I’m already running a website on Webflow, the tool itself is relatively simple, there’s no backend involved, and there’s no sensitive code or data that needs to be hidden, I can add a small tool directly to my existing site without setting up and maintaining a separate service on something like Vercel. That was probably the biggest advantage for me.
Instead of creating another service or channel from scratch, I could simply add the tool as another page on a website I already maintain. Visitors get something they can actually use rather than just another piece of content to read. And if the tool itself gets shared elsewhere, it may also give people a new reason to discover the rest of my website.
However, I think the advantages of using Webflow diminish quickly as the tool becomes more complex. Building something other than a conventional web page required much more custom code than I initially expected. Inputs, checkboxes, responsive behavior, and other parts of the interface all required some combination of custom HTML and CSS.
Writing all of the styles as custom code would defeat one of the reasons I use Webflow in the first place: being able to manage and reuse styles visually. At the same time, relying entirely on Webflow’s built-in UI introduced too many limitations for this kind of tool. I ended up using Webflow’s Style Selectors and native elements wherever possible, then filling in everything I couldn’t reasonably build through the Webflow UI with custom code. The trade-off is that this particular page now has two places I need to maintain: Webflow itself and the custom code layered on top of it.
If the tool were significantly larger, required a backend, or contained implementation details that needed to remain private, I don’t think building it entirely in Webflow would be the right approach.
So, my takeaway is fairly simple. Webflow probably isn’t where I would build a full-scale SaaS product, but for a small interactive tool that lives alongside the rest of an existing website, it can work surprisingly well.