Deduplicate & clean CSS
A big CSS file: exact duplicates, empty rules, repeated properties and overriding rules are merged or removed.
DeduplicateCSS cleanup that keeps the layout
Removes duplicate and unused rules, handles the cascade, CSS variables and inheritance correctly — including styles inherited from body and ancestors.
var() and nested selectorsTools
Three modes for three jobs: clean a file, purge a page, or take the styles of a single block.
A big CSS file: exact duplicates, empty rules, repeated properties and overriding rules are merged or removed.
DeduplicatePaste the page HTML and CSS — only selectors that actually match something in that markup are kept.
FilterThree fields: full page HTML, full page CSS and the block selector. Keeps the block styles, everything inside it, inherited styles of ancestors (including body/html) and CSS variables.
Block exportWhy it is safe
The winning declaration is chosen by importance, specificity and source order. Rules are emitted in their original order, so overrides between equal selectors never break.
Colour, font, line-height, letter-spacing, visibility and SVG fill/stroke come from every ancestor of the block, so nothing loses its look after export.
Both the rules using var(--x) and the rules declaring --x are kept transitively: an --a: var(--b) chain leaves in full, even when declared on another element.
@media, @supports, @layer and @container are filtered recursively and keep their wrapper. A declaration inside @media may not delete the same property from a plain rule.
:hover, :focus, ::before and :has() cannot be resolved statically, so they are always kept: losing a hover state is worse than keeping a spare rule.
Rules before and after, dropped selectors, kept inherited styles and variables, a diff of removed lines — all visible before you copy anything.
For every element we compute the winning value of every property, before and after cleaning. If a single value differs, the test fails.
@media and @supports blocks are dropped entirely@keyframes and @font-face survive only when something references themUse cases
One screen, one stylesheet instead of 180 KB of framework.
Pull a widget out of a legacy project with its ancestors and variables.
A team gets only its own rules, not other teams headers and footers.
Bootstrap-era leftovers, duplicates and temporary patches.
Export the styles of one page instead of the global site CSS.
Refactors leave dead CSS behind; the report shows it and it goes away.
We port styles only for the screens still on the old markup. The rest never reaches the new project.
Shows which rules the page actually uses and which were written for nothing. Useful for teaching and for code review.
Type a selector in the target field or paste the markup of the block itself and we locate it in the page.
.card, #main, .sidebar__item
Before and after
Averages: the real saving depends on the markup, but dead rules live in almost every project.
How it works
The web UI is free and unlimited. Automation gets a key with a balance: $0.001–$0.003 per request, top up by card or crypto.
# экспорт одного блока по API curl -X POST https://css-cleaner.ru/api/v1/block \ -H "X-Api-Key: $CSSCLEANER_KEY" \ -d html=@page.html -d css=@site.css \ -d target=.card \ | jq -r .css > card.css
Details
The winning declaration is chosen by importance, specificity and source order; overriding rules are merged safely.
Inherited properties from html, body and any ancestor of the block are kept, so text never loses its font or colour.
Rules using var() and every declaration of the variables they need are kept transitively, including --x: var(--y).
@media, @supports and @layer are filtered recursively and keep their structure and rule order.
Questions
A duplicate is a rule with the same selector and declaration set; exact copies are removed with no visual change. Overriding rules are merged only when no rule of equal specificity with a conflicting property sits between them, because source order decides the winner there.
Selectors are translated to XPath and matched against the page DOM. For every element the cascade winner is computed from importance, specificity and source order; declarations that never win are reported as not rendered.
color, font-family, font-size, line-height, letter-spacing, text-align, visibility, fill/stroke and custom properties are inherited. Exporting only the block's own rules would lose the font and color, so all ancestor rules — including html and body — are kept.
Rules declaring custom properties (:root { --x: … }) and every rule using var() are kept, and variables declared on ancestors of the block are pulled in automatically.
Yes: paste the full page HTML and CSS and give the block selector. You get the block's rules, everything inside it, inherited ancestor styles and the variables.
The web UI is free and unlimited. The JSON API is billed per key balance from $0.001 per request, paid by card via YooKassa or with crypto.
Your file goes nowhere: processing happens in our own process, nothing is stored or shared.