Back to Blog

The Convert Button Was the Whole Page

September 6, 2026
Share:
The Convert Button Was the Whole Page

I typed #ff0000 into a hex to rgb page. The field sat there. Nothing happened until I pressed Convert. Then I got rgb(255, 0, 0) and a strip of ads under the answer. HSL lived on a different URL. OKLCH was not on the site.

I do this several times a day. A hex out of a design file has to become rgba() for a token, or oklch() for a new stylesheet. Opening three pages for one color is a stupid shape.

The color format converter on Softery is one box. Type. Every other format fills in. Copy the row you need. I built it because I was tired of paying a click and a banner for a parse the browser can do before the next keystroke.

One Direction Per URL

RapidTables has a hex to rgb page. Then a hex to hsl page. Then rgb to hex. Each URL does one pair. Each one wants a click. The ranking notes said the layout also breaks on a phone, so the input and the result are not even on the same screen.

W3Schools has a color picker. It stops at the spaces CSS had in 2012. No oklch. No lab. No display-p3.

A lot of clones copied that shape and added a Convert button so a page view could fire before the answer showed. The button is a pause for the ad.

Those pages work if you want one pair and you don't mind the click. I wanted every format on one screen, including the ones a 2012 page never heard of. I also wanted to type with one hand on a laptop and still see the oklch row without scrolling past a banner.


Rank 13 of 1,754

I ranked this idea thirteenth out of 1,754, score 9.30, about six hours of work. The card said paste any notation, print every other one live, copy on each row, and skip the Convert click. Include oklch, lab, lch and color(display-p3).

The design pile on that list is long. A contrast checker sat at seven and already shipped. A palette-from-image tool is sitting further down. This one sat at thirteen because the search is old and the format people paste now is new.

culori was already in the repo from the contrast checker. I did not add a second color library. One parser, one set of printers, tests that fail before they pass.


19 Completions for a 2012 Job

Bing filled in 19 completions on hex to rgb. hex to rgba. hex to rgb converter. hex to rgb calculator. hex to rgb 0-1. hex to hsl has its own cluster: converter, color, hsla, the reverse.

Those queries have not changed in a decade. The pages that answer them have not changed either. That is why they still win the click. It is also why they still stop at hsl.

I did not invent a search volume. I have the completion list from the ranking pass. Nineteen strings people type after hex to rgb. One of them is 0-1. That row is on the page because the list asked for it, not because I thought it looked modern.


859 Points on a Color Space

A Hacker News thread from August 25, 2025 is titled like this:

What are OKLCH colors?

That is item 45010876. I opened it today. 859 points. 183 comments.

The comments argue about interpolation and gamut mapping. The top one walks through why a gradient in oklch can leave sRGB for most of the trip around the hue circle, and why a straight line in oklab goes through grey on purpose. They are not arguing about whether oklch exists. Browsers print oklch(). Design tools hand you those strings. The converters that stopped in 2012 still shrug.

I will not try to win that thread. I will print the string you can paste into a stylesheet.

The r/webdev contrast thread that ranked the checker also carried a literal ask to add oklch. That ask is why this page exists next to that one.


The Convert Button Was the Product

Here is the whole difference, in one table.

The old pageThis page
InputOne field, then ConvertOne field. The rows update as you type.
OutputOne pair per URLHex, rgb, hsl, oklch, lab, lch, display-p3, rgb 0-1
AlphaOften droppedEight-digit hex, hsla, a slash on oklch
AdsAround the answerNone on this page
PhoneInput and result fight for the screenThe same list, just narrower

A Convert click was the product because each URL did one pair and then showed an ad. If the answer appeared while you typed, the pause went away, and so did the reason to sit on the page.

I kept the swatch and the copy buttons. I did not keep the pause.


One Box, Eight Rows

Type #ff0000. You get rgb(255, 0, 0). You get hsl(0, 100%, 50%). You get 1, 0, 0. You also get oklch, lab, lch and color(display-p3), each rounded so you can paste them.

RowWhat it is for
HEXTokens, Figma, old CSS
RGBrgba() in a stylesheet, or the same numbers with a comma
HSLThe space a lot of sliders still speak
OKLCHWhat a modern file wants
LABThe Cartesian cousin of LCH
LCHPolar lab, if that is what the spec said
Display P3Wide gamut, when hex would lie
RGB 0-1Shaders, canvases, the Bing ask

#f00 works. f00 works. A hash is optional. tomato works. Navy becomes #000080. rebeccapurple becomes #663399.

There is a native color picker next to the field if you would rather click than type. It writes hex, because that is what the control can hold. The rows still print the rest.


Alpha Is a Channel

rgba(255, 0, 0, 0.5) prints #ff000080. It prints hsla(0, 100%, 50%, 0.5). It prints a slash on the oklch row.

The contrast checker on this site clips through sRGB bytes and drops alpha. That is the right call for a ratio. A contrast number does not care that you were at 50 percent opacity. A converter does.

I wrote a second parser so this page could keep the fourth channel. Sharing the contrast parser would have been the lazy path, and it would have lied on every faded swatch. A shared helper that silently drops alpha is the kind of reuse that looks tidy in a review and then bites you on the first translucent token.

Eight-digit hex without a hash works too. 00ff0080 is a green at about half. The page will say so. If you paste #00ff0080 and copy HEX, you get the eight digits back, not a six-digit lie that pretends the color was solid.


Out of Gamut Is Not a Crash

oklch can describe a color sRGB cannot show. The hex row is the clipped sRGB byte, the one a hex field can hold. The oklch row keeps what you typed, rounded. That is the honest split.

If you need the wide-gamut print, copy display-p3. Do not copy the hex and pretend it is the same color. It is the nearest byte.

The HN thread talks about dragging colors back in gamut, and about how those algorithms disagree. I did not invent a mapping. I print both sides and let you pick. A crash would be worse, and a silent clip with no oklch row would be a lie.

I rounded oklch lightness and chroma to four decimals, hue to two. Lab and lch get two. Display-p3 gets four. That is enough to paste and not so many digits that the row looks like a dump. If you need more precision than that, you are not on a converter page anymore. You are in a notebook.


RGB 0-1 Is a Real Ask

#808080 is 128 out of 255. The 0-1 row prints 0.502, 0.502, 0.502. Three decimals when a channel is not 0 or 1. Red stays 1, 0, 0.

People search hex to rgb 0-1 because a shader and a CSS file do not speak the same scale. The old pages print 128 and leave you to divide. This row does the divide.

I am not going to add CMYK on the same sitting. The Bing list asked for it. Print and screen are different jobs. A CMYK number that came from a cheap matrix would look confident and be wrong. I'd rather leave the row off.


Nothing Is Saved

Refresh and the field is empty. Close the tab and the paste is gone. After the page loads you can unplug the cable and still get oklch from a hex.

I did not add a permalink. A shared URL with the color in the query would be useful. It is not on the page today. A color in a query string also ends up in server logs, and this page's promise is that the string stays in the tab.

Mixpanel and Google Analytics load with Softery.io. They see that someone opened the tool. On the first valid parse they get a size bucket. On a copy they get the format name, hex or oklch, not the value. They do not get #ff0000.

If that is still too much, the math has already run. Block the scripts. The rows still update.


What This Page Will Not Do

It will not call a model. There is no API after the page loads. A color in, eight strings out, is a parse. Sending that to a model would be theater.

It will not upload the color. It will not keep the field overnight. It will not score the color as on-brand. It will not suggest a palette.

If you need two colors against WCAG, use the contrast checker. If you need inches to cm, use the unit converter. If you want a PDF of a spec that now has the right oklch, paste it into Markdown to PDF.


How I Tested It

I wrote the tests first. Eleven on the parser. Seven on the page. They failed, then they passed. That is the house rule here, and it is the only reason I trust #ff0000 to print hsl(0, 100%, 50%) every time.

The library checks bare hex, three-digit hex, rgb, hsl, oklch, lab, lch, display-p3, named colors, eight-digit hex, rgba at 0.5, junk, transparent, currentcolor, and the sample #3b82f6. The page checks that the rows appear while you type, that Copy HEX writes the string, that alpha copies eight digits, that a sample fills and a clear empties, and that junk gets a sentence instead of a fake color.

transparent and currentcolor return nothing on purpose. They are keywords, not colors you can print in eight spaces. inherit and unset go the same way. A random word gets the same empty result, plus a line that says I could not read it.

There is no Convert button in the tests because there is no Convert button on the page. A test that looked for one would have been a gift. I also checked that the copy on the page does not hide a Convert control under a different name. The sample button is Paste a sample. That is a fill, not a job.


Paste the Color

If you have a hex, a token, or an oklch() from a design file, paste it.

  1. Open Color Format Converter.
  2. Paste the color. A hash is optional. A name like tomato is fine.
  3. Read the rows. Copy the one your file actually wants.
  4. If the hex looks different from the oklch you pasted, believe the oklch. The hex is the clip.
  5. Open the network panel once if you don't believe the string stayed put.

The other tools on Softery follow the same habit. The password generator never sees the password. The JSON formatter never sends the document. This one never sends the color as text either.


Last updated: September 6, 2026 | Reading time: 10 minutes

Written by Evgeniy Poznyak, who still opens a converter more often than he wants to admit.