PHPackages                             thomasperi/yacssmin - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. thomasperi/yacssmin

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

thomasperi/yacssmin
===================

Yet Another CSS Minifier

v0.7.1(6y ago)014MITCSSPHP &gt;=5.6CI failing

Since Apr 30Pushed 6y agoCompare

[ Source](https://github.com/thomasperi/yacssmin)[ Packagist](https://packagist.org/packages/thomasperi/yacssmin)[ RSS](/packages/thomasperi-yacssmin/feed)WikiDiscussions master Synced 2d ago

READMEChangelogDependencies (2)Versions (13)Used By (0)

YaCSSMin
========

[](#yacssmin)

Yet Another CSS Minifier

Why?
----

[](#why)

Why write another CSS Minifier? Read [PHILOSOPHY.md](PHILOSOPHY.md).

Installation
------------

[](#installation)

**Composer**
In your project directory:

```
composer require thomasperi/yacssmin

```

**Manually**
Download [Minifier.php](https://raw.githubusercontent.com/thomasperi/yacssmin/master/src/Minifier.php) and `require` it in your PHP app:

```
require '/path/to/Minifier.php';
```

Usage
-----

[](#usage)

```
use \ThomasPeri\YaCSSMin\Minifier;
$minified_css = Minifier::minify($css);
```

### Return Value

[](#return-value)

The `minify` method returns a minified string when it successfully minifies a stylesheet. If it returns `false`, it means that the CSS code contained an un-balanced brace, bracket, parenthesis, comment, or string; or an unescaped newline inside a string. To distinguish this from the empty string, use strict comparison:

```
$minified_css = Minifier::minify($css);
if (false === $minified_css) {
    // Error
} else {
    // Success
}
```

### Preserving Comments

[](#preserving-comments)

The `minify` method also accepts an optional second argument which should be an array of options.

You can selectively preserve comments by writing a callback function for filtering each comment, and passing it in as the `comments` option. This callback should accept a full comment (beginning with `/*` and ending with `*/`) and return a full comment. To preserve a comment as-is, you can just return the string that was passed in:

```
// Preserve any comments that contain the string `@license`:
$minified_css = Minifier::minify($css, [
    'comments' => function ($comment) {
        if (false !== strpos($comment, '@license')) {
            return $comment;
        }
    }
]);
```

If it returns `null` or anything other than a valid CSS comment, the comment will be stripped from the output.

### Content Filtering

[](#content-filtering)

The other option available is to pass in a custom filter to alter the CSS beyond what YaCSSMin does on its own.

YaCSSMin only removes whitespace and comments. It doesn't change any of the values in your CSS, like shortening color codes or rewriting URLs. (For reasons why, see [PHILOSOPHY.md](PHILOSOPHY.md).) So to do things like that, you need the `filter` option:

```
// Preserve any comments that contain the string `@license`:
$minified_css = Minifier::minify($css, [
    'filter' => function ($css, &$strings, &$comments) {
        // ... do stuff that modifies $css, then return the modified copy ...
        return $css;
    }
]);
```

Here are the arguments that function should accept:

ArgumentDescription`$css`A string containing the minified stylesheet, with every string represented by the placeholder `"_"`, and preserved comments represented by `/*_*/`.`&$strings`An array of strings (including quotes) corresponding, in order, to the `"_"` placeholders.`&$comments`An array of comments corresponding, in order, to the `/*_*/` placeholders.If you remove a string or a comment from `$css`, be sure to also `unset` or `array_splice` it out of `&$strings` or `&$comments`, to keep them in sync.

There might also be comments (`/**/`) that were only emptied rather than stripped, because of weird placement. These have no counterpart in the `&$comments` array.

#### Example

[](#example)

Here a stub of what rewriting URLs could look like, minus the actual rewriting part.

```
$minified_css = Minifier::minify($css, [
    'filter' => function ($css, &$strings) {
        $pattern = '#"_"|url\((.+?)\)#i';
        $i = 0;
        $rewrite = function ($url) {
            // ... make your changes to $url here ...
            return $url;
        };
        return preg_replace_callback(
            $pattern,
            function ($matches) use (&$i, &$strings, $rewrite) {
                $match = $matches[0];
                switch (strtolower($match)) {
                    // Skip over strings that aren't URLs, but count them.
                    case '"_"':
                        $i++;
                        break;

                    // Found a string that contains a URL. Rewrite the string
                    // in the array, but leave the placeholder unchanged.
                    case 'url("_")':
                        // Separate the URL from the quotes, rewrite the URL,
                        // and put the quotes back on.
                        $string = $strings[$i];
                        $quote = substr($string, 0, 1);
                        $url = substr($string, 1, strlen($string) - 2);
                        $strings[$i] = $quote . $rewrite($url) . $quote;
                        $i++;
                        break;

                    // Unquoted URLs aren't stashed as strings, so do the
                    // rewrite on what was found inside url(...).
                    default:
                        $match = 'url(' . $rewrite($matches[1]) . ')';
                }
                return $match;
            },
            $css
        );
    }
]);
```

Pronunciation
-------------

[](#pronunciation)

/ YAX min /

###  Health Score

23

—

LowBetter than 26% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~25 days

Recently: every ~68 days

Total

12

Last Release

2334d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/33704731?v=4)[Thomas Peri](/maintainers/thomasperi)[@thomasperi](https://github.com/thomasperi)

---

Top Contributors

[![thomasperi](https://avatars.githubusercontent.com/u/33704731?v=4)](https://github.com/thomasperi "thomasperi (55 commits)")

---

Tags

csslibraryminifierphp

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/thomasperi-yacssmin/health.svg)

```
[![Health](https://phpackages.com/badges/thomasperi-yacssmin/health.svg)](https://phpackages.com/packages/thomasperi-yacssmin)
```

###  Alternatives

[kunststube/rison

A PHP encoder and decoder for Rison, the compact JSON-like data format optimized for URIs.

2367.3k3](/packages/kunststube-rison)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
