lightningcss
lightningcss copied to clipboard
Merging adjacent rules with *almost* the same declarations
README says:
Merging adjacent rules with the same selectors or declarations when it is safe to do so.
This works as advertised:
.foo {
background-color: red;
}
.bar {
background-color: red;
}
/* output */
.foo,.bar{background-color:red}
But I wonder, is there any reason not to merge partially-indentical rules?
.foo {
background-color: red;
padding: 20px;
}
.bar {
background-color: red;
padding: 40px;
}
/* actual output */
.foo{background-color:red;padding:20px}.bar{background-color:red;padding:40px}
/* better output? */
.foo,.bar{background-color:red}.foo{padding:20px}.bar{padding:40px}
/* or maybe even: */
.foo,.bar{background-color:red;padding:20px}.bar{padding:40px}
Or am I wrong to think that as long as the rules are adjacent, this should be safe to do?
(The gains aren't big in this simplified example, but we have CSS with long adjacent rules that differ in only one or two declarations, and it quickly adds up.)
Note that in some cases, depending on the selector length, this may actually make the output larger. For example:
.somelongselectorname{background-color:red;padding:20px}.someotherlongselectorname{background-color:red;padding:40px}
.somelongselectorname,.someotherlongselectorname{background-color:red;padding:20px}.someotherlongselectorname{padding:40px}
Yeah, that's fair. Out of curiosity I checked what csso
does, and it seems to be using whichever ends up shorter.
Just to add a practical example to this conversation, what we're dealing with is more like:
/* optimal? output */
.framer-iekIZ .framer-1kq0lbv,
.framer-iekIZ .framer-1x8f0vg,
.framer-iekIZ .framer-cbkbdb {
align-content: center;
align-items: center;
display: flex;
flex: none;
flex-direction: column;
flex-wrap: nowrap;
height: min-content;
justify-content: flex-start;
overflow: hidden;
position: relative;
width: 100%;
}
.framer-iekIZ .framer-1kq0lbv {
background-color: #fff;
gap: 70px;
padding: 100px 0 0;
}
.framer-iekIZ .framer-1x8f0vg {
background-color: var(--token-26e3cb56-8447-4a64-9b7d-37f16a9909d4, #ffffff);
gap: 80px;
padding: 100px 50px 60px;
}
.framer-iekIZ .framer-cbkbdb {
gap: 0;
padding: 0;
}
Without merging the rules like that, we end up with the first chunk of declarations repeated 3 times.
Hey @devongovett, friendly bump for this one here. While taking a look into LightningCSS, I've compared it to csso and this seemed to be the reason why the output of lightningcss is slightly larger compared to csso.