stoyan / cssshrink

CSS minifier
1.05k stars 81 forks source link

Duplicate removal #7

Closed beausmith closed 10 years ago

beausmith commented 10 years ago

Should cssshrink remove duplicates?

It does when the duplicates are adjacent siblings:

@media print {b {color: #fff;}}
@media print {a {color: #000;}}
@media print {b {color: #fff;}}

Out:

@media print{b{color:#fff}a{color:#000}}

But not when they aren't:

@media print {b {color: #fff;}}
@media print {a {color: #000;}}
@media print {b {color: #fff;}}

Out:

@media print{b{color:#fff}a{color:#000}b{color:#fff}}

Resolve if works as expected. =)

goddyZhao commented 10 years ago

These two samples look like the same.

arildrotmo commented 10 years ago

Looks like a slight oversight by @beausmith . Typo in his first example, which should be:

CSS in:

@media print {b {color: #fff;}}
@media print {a {color: #000;}}
@media print {b {color: #fff;}}

CSS out:

@media print{b{color:#fff}a{color:#000}b{color:#fff}}

Expected:

@media print{b{color:#fff}a{color:#000}}

When a property is declared twice on an element, only the last declaration will have any effect, so anything else can be removed. Another example:

CSS in:

@media print {b {color: #fff; color: #000;}}

CSS out:

@media print{b{color:#fff;color:#000}}

Expected:

@media print{b{color:#000}}

Except of course if you declare font-size in rems with a px fallback, and similar situations.

stoyan commented 10 years ago

Thanks everyone!

two things here

first

.b{...}
.a{...}
.b{...}

if not safe to resolve to

.b{...}
.a{...}

Imagine both selectors apply to the same element and they have the same specificity. So .b wins by being last. If you move .a to be last than .a wins.

That's why duplicates in selectors, blocks, media etc are only merged when they are adjacent

Second

a {color: red; color: blue}

is on my todo

There can be sometimes intentional duplicates, for backwards compat. Will need to figure out a safe way to dedup.

And thanks again!