Free CSS & JS Tools
Front-end developer utilities — minify and beautify CSS / JS, build CSS gradients visually. All browser-side.
Which tool for which job
Minifying and formatting are the same operation pointed in opposite directions. You minify on the way out (a snippet pasted into a <style> block, an email template with a size budget) and format on the way in (a vendor file, a stylesheet a CMS mangled).
Rough decision list:
- Your build already minifies: skip the tool. esbuild, or Rollup and Vite with a minifier attached, see the whole module graph and drop unreachable exports too.
- No build step at all (a static page, a WordPress theme, a CMS HTML block): minify here, paste the result, keep the source file next to it.
- Diffing two files formatted by different people: format both first, so the diff shows real changes, not brace placement.
What minification actually removes
Comments, whitespace, the final semicolon in a block, and in CSS the leading zero on decimals (0.5em becomes .5em) and the quotes in url("hero.png") when the path needs no escaping. A rule like
.card { margin: 0px auto; color: #ffffff; }
comes out as .card{margin:0 auto;color:#fff}. That is typically 20-35% off a hand-written stylesheet, and far less once the file is compressed in transit, so judge the win on the compressed size.
Where it goes wrong
JavaScript minification is riskier than CSS because it has to parse. Things that bite people:
- Missing semicolons. Code that relies on automatic semicolon insertion can break when lines are joined. A line ending in
)followed by a line starting with(or[is the classic case. - Syntax the minifier is too old to parse. Optional chaining,
??=, class fields, top-levelawait. UglifyJS only handles ES5 and reports a parse error at the first arrow function or?.it meets. Terser and esbuild take current syntax. - Names referenced as strings. Terser leaves top-level names and object properties alone by default. Switch on top-level mangling, or run the file through a bundler, and a function reached only from
window["myHandler"]or an inlineonclick="init()"loses the name that string looks for. - Licence headers. Blocks marked
/*!or containing@licenseare conventionally preserved; a plain/* ... */licence is not, and stripping it can breach the terms.
CSS has fewer traps but two that recur: IE hacks such as *zoom or _height are dropped unless the tool is put in a legacy compatibility mode, and a missing closing brace makes every rule below it vanish rather than error, because the rest of the file is read as declarations inside the open block. If a stylesheet loses its footer styling, look for a missing } above.
Checking the output
Do not eyeball minified code. Format the result and diff it against the formatted original: everything that differs should be a rename or a shorthand collapse, nothing structural. For JS, load the page and watch the console.
These tools run entirely in your browser tab, so the file never leaves the machine. That matters when the script holds an analytics key, or your employer counts a third-party code paste as a reportable event.
Common questions
Is minified CSS still valid CSS? Yes. Whitespace around braces, colons and semicolons carries no meaning, so a{color:red} parses the same as an indented version. Some spaces do carry meaning and are kept: the descendant combinator in .card .title, the spaces around + and - inside calc(), and anything inside a quoted string.
Can I get my original file back after minifying? No. Formatting restores structure but not comments or original names, which are gone for good. Keep the source in version control and treat the minified file as build output.
Why did minifying save so little once the file was compressed? Because gzip was already squeezing the repetition that minification deletes. A 100 KB stylesheet might sit at 22 KB gzipped, minify to 70 KB, and gzip to 20 KB. The 30 KB looks impressive; the 2 KB is what the visitor saves.
Does formatting change how the browser renders my CSS? No. A formatter only adds line breaks and indentation, so cascade order and specificity are untouched. If your rendering changed, something re-sorted your rules rather than reformatting them.