User Rating 0.0
Total Usage 0 times
Category CSS Tools
CSS Input
LESS Output
Is this tool helpful?

Your feedback helps us improve.

About

Raw CSS files grow unmanageable past a few hundred lines. Duplicate color values scatter across selectors, vendor-prefixed properties triple your line count, and flat selector lists obscure the DOM hierarchy they target. This converter parses your CSS into an abstract syntax tree, then reconstructs it as valid LESS with nested selectors, extracted @color variables, and vendor-prefix mixins. The nesting algorithm computes the longest common selector prefix chain so .nav, .nav ul, and .nav ul li collapse into a single nested block. Color extraction uses deduplication: if #3498db appears 12 times, it becomes one @color-1 declaration. The tool approximates optimal nesting assuming well-structured selectors. Deeply combinator-mixed selectors (e.g., div > .a + .b ~ .c) may produce verbose nesting where manual grouping would be cleaner.

css to less less converter css nesting less variables css preprocessor convert css less mixins

Formulas

The conversion pipeline applies three transformations in sequence. First, selector nesting groups flat CSS rules into a tree hierarchy.

nest(S) = trie(S1, S2, … Sn)

where each selector Si is split by whitespace and combinator tokens into segments. The trie merges common prefixes so that .a .b and .a .c share the .a node. Pseudo-selectors (:hover, ::after) are detected via leading : and rendered with the & parent reference operator.

Spseudo &Spseudo

Second, color variable extraction scans all property values with the pattern:

regex = #[0-9a-fA-F]{3,8} | rgb() | rgba() | hsl() | hsla()

Each unique color is assigned @color-N where N N. All occurrences are replaced with the variable reference.

Third, vendor mixin generation detects property groups where the base property name (stripped of prefix) matches across 2+ vendor prefixes from the configured list. These collapse into a parametric mixin:

.vendor-mixin(@value) { -webkit-prop: @value; prop: @value; }

Reference Data

OptionTypeDefaultDescription
indentSizeNumber1Number of indent symbols per nesting level
indentSymbolString\t (tab)Character used for indentation: tab or spaces
selectorSeparatorString,\nSeparator between grouped selectors
blockFromNewLineBooleanFALSEPlace opening { on a new line (Allman style)
blockSeparatorString\nWhitespace between rule blocks
updateColorsBooleanFALSEExtract color literals into @color-N variables
vendorMixinsBooleanTRUECollapse vendor-prefixed properties into LESS mixins
vendorPrefixesListArray-moz, -o, -ms, -webkitVendor prefixes to detect and collapse
LESS Language Features Used
NestingChild selectors become nested blocks: .parent { .child { } }
VariablesRepeated values extracted to @var: value; at file top
MixinsVendor groups become .mixin(@val) { -webkit-prop: @val; prop: @val; }
& OperatorPseudo-classes/elements use &:hover, &::before
CommentsOriginal CSS comments preserved in output
Common CSS Constructs Handled
@mediaMedia queries preserved as top-level blocks with nested content
@keyframesKeyframe blocks passed through without nesting modification
@font-faceFont-face declarations preserved as-is
@importImport statements hoisted to file top
@charsetCharset declarations hoisted to first line
@supportsFeature queries preserved as top-level blocks

Frequently Asked Questions

The parser splits selectors on whitespace but preserves combinator tokens (>, +, ~) attached to the following segment. When building the nesting trie, a segment like "> .child" is treated as a distinct node from ".child". This means ".parent > .child" and ".parent .child" will NOT merge into the same nested block, which is correct LESS behavior since they target different DOM relationships.
The color extraction uses boundary-aware matching. A color inside a gradient like "linear-gradient(#fff, #000)" will have each color token replaced individually with its variable, producing "linear-gradient(@color-1, @color-2)". The surrounding function syntax is preserved. However, shorthand hex values (#fff) and their longform equivalents (#ffffff) are treated as separate colors. Normalize your CSS hex values before conversion for optimal variable deduplication.
Media queries remain as top-level blocks. Rules inside them are nested independently using the same algorithm. @keyframes blocks are passed through verbatim since their internal selectors (0%, 100%, from, to) are not DOM selectors and should not be nested. @font-face, @charset, and @import are similarly preserved without modification.
The generated LESS, when compiled with lessc, will produce functionally equivalent CSS. It will not be byte-identical because the LESS compiler may reorder properties within a rule, normalize whitespace differently, and expand mixins in a specific order. Semantic equivalence is guaranteed; lexical identity is not.
Mixin names are derived from the base property name with a ".vendor-" prefix. For example, "-webkit-border-radius" and "-moz-border-radius" produce ".vendor-border-radius(@value)". If your existing LESS codebase already defines a mixin with that name, you will get a compilation conflict. Review generated mixin names before merging into an existing LESS project.
The converter operates entirely in-browser. Practical limits depend on available memory. Stylesheets under 500KB (roughly 15,000 rules) process in under 2 seconds on modern hardware. Files over 1MB may cause noticeable delay. The parser does not use Web Workers for this task, so the UI thread will block briefly during conversion of very large files.