PHPackages                             wikimedia/css-sanitizer - 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. [Validation &amp; Sanitization](/categories/validation)
4. /
5. wikimedia/css-sanitizer

ActiveLibrary[Validation &amp; Sanitization](/categories/validation)

wikimedia/css-sanitizer
=======================

Classes to parse and sanitize CSS

v6.2.1(2mo ago)165.1M↑19.5%71Apache-2.0PHPPHP &gt;=8.1

Since Apr 6Pushed 2mo ago12 watchersCompare

[ Source](https://github.com/wikimedia/css-sanitizer)[ Packagist](https://packagist.org/packages/wikimedia/css-sanitizer)[ Docs](https://www.mediawiki.org/wiki/Css-sanitizer)[ RSS](/packages/wikimedia-css-sanitizer/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (20)Versions (25)Used By (1)

[![Latest Stable Version](https://camo.githubusercontent.com/dcbde5b746dd58564d44e8ec4a34cf287d84b7bb3f2d2e277bd91d06954775aa/68747470733a2f2f706f7365722e707567782e6f72672f77696b696d656469612f6373732d73616e6974697a65722f762f737461626c652e737667)](https://packagist.org/packages/wikimedia/css-sanitizer) [![License](https://camo.githubusercontent.com/7d8cdb6421f2d4f65d5579c9409e996425b04550ad54ad62abcd9add2cb91732/68747470733a2f2f706f7365722e707567782e6f72672f77696b696d656469612f6373732d73616e6974697a65722f6c6963656e73652e737667)](https://packagist.org/packages/wikimedia/css-sanitizer)

Wikimedia CSS Parser &amp; Sanitizer
====================================

[](#wikimedia-css-parser--sanitizer)

This library implements a CSS tokenizer, parser and grammar matcher in PHP.

Usage
-----

[](#usage)

```
use Wikimedia\CSS\Parser\Parser;
use Wikimedia\CSS\Sanitizer\StylesheetSanitizer;

/** Parse a stylesheet from a string **/

$parser = Parser::newFromString( $cssText );
$stylesheet = $parser->parseStylesheet();

/** Report any parser errors **/

foreach ( $parser->getParseErrors() as list( $code, $line, $pos ) ) {
	// $code is a string that should be suitable as a key for an i18n library.
	// See errors.md for details.
	$error = lookupI18nMessage( "css-parse-error-$code" );
	echo "Parse error: $error at line $line character $pos\n";
}

/** Apply sanitization to the stylesheet **/

// If you need to customize the defaults, copy the code of this method and
// modify it.
$sanitizer = StylesheetSanitizer::newDefault();
$newStylesheet = $sanitizer->sanitize( $stylesheet );

/** Report any sanitizer errors **/

foreach ( $sanitizer->getSanitizationErrors() as list( $code, $line, $pos ) ) {
	// $code is a string that should be suitable as a key for an i18n library.
	// See errors.md for details.
	$error = lookupI18nMessage( "css-sanitization-error-$code" );
	echo "Sanitization error: $error at line $line character $pos\n";
}

/** Convert the sanitized stylesheet back to text **/

$newText = (string)$newStylesheet;

// Or if you'd rather have it minified too
$minifiedText = Wikimedia\CSS\Util::stringify( $newStylesheet, [ 'minify' => true ] );
```

Conformance
-----------

[](#conformance)

The library follows the following grammar specifications:

- [CSS Syntax Level 3, 2019-07-16](https://www.w3.org/TR/2021/CRD-css-syntax-3-20211224/)
- [CSS Values and Units Module Level 4, 2024-03-12](https://www.w3.org/TR/2024/WD-css-values-4-20240312/)
- [CSS Selectors Level 3, 2018-11-06](https://www.w3.org/TR/2018/REC-selectors-3-20181106/)

The sanitizer recognizes the following CSS modules:

- [Align Level 3, 2025-03-11](https://www.w3.org/TR/2025/WD-css-align-3-20250311/)
- [Animations Level 1, 2023-03-02](https://www.w3.org/TR/2023/WD-css-animations-1-20230302/)
- [Backgrounds Level 3, 2024-03-11](https://www.w3.org/TR/2024/CRD-css-backgrounds-3-20240311/)
- [Break Level 3, 2018-12-04](https://www.w3.org/TR/2018/CR-css-break-3-20181204/)
- [Cascade Level 4, 2022-01-13](https://www.w3.org/TR/2022/CR-css-cascade-4-20220113/)
- [Color Level 4, 2025-04-24](https://www.w3.org/TR/2025/CRD-css-color-4-20250424)
- [Compositing Level 1, 2024-03-21](https://www.w3.org/TR/2024/CRD-compositing-1-20240321/)
- [Counter Styles Level 3, 2021-07-27](https://www.w3.org/TR/2021/CR-css-counter-styles-3-20210727/)
- [CSS Level 2, 2011-06-07](https://www.w3.org/TR/2011/REC-CSS2-20110607/)
- [Display Level 3, 2023-03-30](https://www.w3.org/TR/2023/CR-css-display-3-20230330/)
- [Easing Level 1, 2023-02-13](https://www.w3.org/TR/2023/CRD-css-easing-1-20230213/)
- [Filter Effects Level 1, 2018-12-18](https://www.w3.org/TR/2018/WD-filter-effects-1-20181218)
- [Flexbox Level 1, 2018-11-19](https://www.w3.org/TR/2018/CR-css-flexbox-1-20181119)
- [Fonts Level 3, 2018-09-20](https://www.w3.org/TR/2018/REC-css-fonts-3-20180920)
- [Grid Level 1, 2025-03-26](https://www.w3.org/TR/2025/CRD-css-grid-1-20250326/)
- [Images Level 3, 2023-12-18](https://www.w3.org/TR/2023/CRD-css-images-3-20231218/)
- [Lists and Counters Level 3, 2020-11-17](https://www.w3.org/TR/2020/WD-css-lists-3-20201117/)
- [Logical Properties and Values Level 1, 2018-08-27](https://www.w3.org/TR/2018/WD-css-logical-1-20180827/)
- [Masking Level 1, 2021-08-05](https://www.w3.org/TR/2021/CRD-css-masking-1-20210805/)
- [Multicol Level 1, 2019-10-15](https://www.w3.org/TR/2024/CR-css-multicol-1-20240516/)
- [Overflow Level 3, 2023-03-29](https://www.w3.org/TR/2023/WD-css-overflow-3-20230329/)
- [Overflow Level 4, 2023-03-21](https://www.w3.org/TR/2023/WD-css-overflow-4-20230321/)
- [Page Level 3, 2023-09-14](https://www.w3.org/TR/2023/WD-css-page-3-20230914/)
- [Position Level 3, 2025-03-11](https://www.w3.org/TR/2025/WD-css-position-3-20250311/)
- [Pseudo-Elements Level 4, 2022-12-30](https://www.w3.org/TR/2022/WD-css-pseudo-4-20221230/)
- [Ruby Level 1, 2022-12-31](https://www.w3.org/TR/2022/WD-css-ruby-1-20221231/)
- [Scroll Snap Module Level 1](https://www.w3.org/TR/2021/CR-css-scroll-snap-1-20210311/)
- [Shapes Level 1, 2022-11-15](https://www.w3.org/TR/2022/CRD-css-shapes-1-20221115/)
- [Sizing Level 3, 2021-12-17](https://www.w3.org/TR/2021/WD-css-sizing-3-20211217/)
- [Sizing Level 4, 2025-02-24](https://drafts.csswg.org/css-sizing-4/)
- [Text Level 3, 2024-09-30](https://www.w3.org/TR/2024/CRD-css-text-3-20240930/)
- [Text Decorations Level 3, 2022-05-05](https://www.w3.org/TR/2022/CRD-css-text-decor-3-20220505/)
- [Transforms Level 1, 2019-02-14](https://www.w3.org/TR/2019/CR-css-transforms-1-20190214)
- [Transforms Level 2, 2021-11-09](https://www.w3.org/TR/2021/WD-css-transforms-2-20211109/)
- [Transitions Level 1, 2018-10-11](https://www.w3.org/TR/2018/WD-css-transitions-1-20181011)
- [UI 3 Level 3, 2018-06-21](https://www.w3.org/TR/2018/REC-css-ui-3-20180621)
- [UI 4 Level 4, 2021-03-16](https://www.w3.org/TR/2021/WD-css-ui-4-20210316/)
- [Writing Modes Level 4, 2019-07-30](https://www.w3.org/TR/2019/CR-css-writing-modes-4-20190730)

And also,

- The `touch-action` property from [Pointer Events Level 2, 2019-04-04](https://www.w3.org/TR/2019/REC-pointerevents2-20190404/)
- `:dir()` pseudo-class from [Selectors Level 4, 2022-11-11](https://www.w3.org/TR/2022/WD-selectors-4-20221111/#the-dir-pseudo)
- Accessibility related media features from [Media Queries Level 5](https://drafts.csswg.org/mediaqueries-5/#mf-user-preferences) including prefers-reduced-motion, prefers-reduced-transparency, prefers-contrast and forced-colors.
- `light-dark()` color function from [Color Module Level 5, 2024-02-29](https://www.w3.org/TR/2024/WD-css-color-5-20240229/#funcdef-light-dark)

Running tests
-------------

[](#running-tests)

```
composer install --prefer-dist
composer test

```

Adding properties
-----------------

[](#adding-properties)

CSS specifications typically contain a summary of value grammars in the property index section. These value grammars map directly to PHP code.

[Component value types](https://www.w3.org/TR/css-values-4/#component-types)

Syntaxcss-sanitizer code`foo``new KeywordMatcher( 'foo' )``foo | bar``new KeywordMatcher( [ 'foo', 'bar' ] )````$matcherFactory->string()````$matcherFactory->url()````$matcherFactory->integer()````$matcherFactory->number()````$matcherFactory->ratio()````$matcherFactory->percentage()````$matcherFactory->length()````$matcherFactory->frequency()````$matcherFactory->angle()````$matcherFactory->time()````$matcherFactory->resolution()`[Component value combinators](https://www.w3.org/TR/css-values-4/#component-combinators)

Syntaxcss-sanitizer code`a b``new Juxtaposition( [ a, b ] )``a && b``UnorderedGroup::allOf( [ a, b ] )``a  || b``UnorderedGroup::someOf( [ a, b ] )``a | b``new Alternative( [ a, b ] )`[Component value multipliers](https://www.w3.org/TR/css-values-4/#component-multipliers)

Syntaxcss-sanitizer code`a*``Quantifier::star( a )``a+``Quantifier::plus( a )``a?``Quantifier::optional( a )``a{3,4}``Quantifier::count( a, 3, 4 )``a#``Quantifier::hash( a )``a!``new NonEmpty( a )`Releasing a new version
-----------------------

[](#releasing-a-new-version)

This package uses `wikimedia/update-history` and its conventions.

See  for details.

History
-------

[](#history)

We required a CSS sanitizer with several properties:

- Strict parsing according to modern standards.
- Includes line and character position for all errors.
- Configurable to limit unsafe constructs such as external URL references.
- Errors are easily localizable.

We could not find a library that fit these requirements, so we created one.

Additional release history is in [`HISTORY.md`](./HISTORY.md).

---

###  Health Score

66

—

FairBetter than 99% of packages

Maintenance86

Actively maintained with recent releases

Popularity53

Moderate usage in the ecosystem

Community29

Small or concentrated contributor base

Maturity82

Battle-tested with a long release history

 Bus Factor3

3 contributors hold 50%+ of commits

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 ~141 days

Recently: every ~100 days

Total

24

Last Release

75d ago

Major Versions

v1.0.6 → v2.0.02018-08-24

v2.0.1 → v3.0.02021-01-04

v3.0.2 → v4.0.02022-07-03

v4.0.1 → v5.0.02023-08-29

v5.5.0 → v6.0.02025-07-23

PHP version history (4 changes)v1.0.0PHP &gt;=5.5.9

v3.0.0PHP &gt;=7.2.0

v5.0.0PHP &gt;=7.4.0

v6.0.0PHP &gt;=8.1

### Community

Maintainers

![](https://www.gravatar.com/avatar/b94d9718c06ec7c3fd7a104bc44966fb7464b9ec7411582343ea35a7a6a85f08?d=identicon)[mediawiki](/maintainers/mediawiki)

![](https://www.gravatar.com/avatar/716c86d71cbf921e7912a505f89d799de398fc0a3af0bd4c8862834b2d642bd7?d=identicon)[wikimedia](/maintainers/wikimedia)

---

Top Contributors

[![umherirrender](https://avatars.githubusercontent.com/u/1174884?v=4)](https://github.com/umherirrender "umherirrender (31 commits)")[![reedy](https://avatars.githubusercontent.com/u/67615?v=4)](https://github.com/reedy "reedy (25 commits)")[![anomiex](https://avatars.githubusercontent.com/u/1030580?v=4)](https://github.com/anomiex "anomiex (23 commits)")[![jdforrester](https://avatars.githubusercontent.com/u/881572?v=4)](https://github.com/jdforrester "jdforrester (16 commits)")[![tstarling](https://avatars.githubusercontent.com/u/389141?v=4)](https://github.com/tstarling "tstarling (14 commits)")[![cscott](https://avatars.githubusercontent.com/u/156080?v=4)](https://github.com/cscott "cscott (8 commits)")[![ebraminio](https://avatars.githubusercontent.com/u/833473?v=4)](https://github.com/ebraminio "ebraminio (6 commits)")[![bawolff](https://avatars.githubusercontent.com/u/6529932?v=4)](https://github.com/bawolff "bawolff (5 commits)")[![moabualruz](https://avatars.githubusercontent.com/u/26027239?v=4)](https://github.com/moabualruz "moabualruz (5 commits)")[![legoktm](https://avatars.githubusercontent.com/u/81392?v=4)](https://github.com/legoktm "legoktm (5 commits)")[![siddharthvp](https://avatars.githubusercontent.com/u/31818903?v=4)](https://github.com/siddharthvp "siddharthvp (4 commits)")[![Daimona](https://avatars.githubusercontent.com/u/38216014?v=4)](https://github.com/Daimona "Daimona (3 commits)")[![Eccenux](https://avatars.githubusercontent.com/u/1045235?v=4)](https://github.com/Eccenux "Eccenux (2 commits)")[![ZabeMath](https://avatars.githubusercontent.com/u/35405030?v=4)](https://github.com/ZabeMath "ZabeMath (1 commits)")[![alistair3149](https://avatars.githubusercontent.com/u/9260542?v=4)](https://github.com/alistair3149 "alistair3149 (1 commits)")[![DannyS712](https://avatars.githubusercontent.com/u/46829944?v=4)](https://github.com/DannyS712 "DannyS712 (1 commits)")[![dringsim](https://avatars.githubusercontent.com/u/57343841?v=4)](https://github.com/dringsim "dringsim (1 commits)")[![lucaswerkmeister](https://avatars.githubusercontent.com/u/2346599?v=4)](https://github.com/lucaswerkmeister "lucaswerkmeister (1 commits)")[![MatmaRex](https://avatars.githubusercontent.com/u/160413?v=4)](https://github.com/MatmaRex "MatmaRex (1 commits)")[![tgr](https://avatars.githubusercontent.com/u/145412?v=4)](https://github.com/tgr "tgr (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/wikimedia-css-sanitizer/health.svg)

```
[![Health](https://phpackages.com/badges/wikimedia-css-sanitizer/health.svg)](https://phpackages.com/packages/wikimedia-css-sanitizer)
```

###  Alternatives

[webmozart/assert

Assertions to validate method input/output with nice error messages.

7.6k894.0M1.2k](/packages/webmozart-assert)[bensampo/laravel-enum

Simple, extensible and powerful enumeration implementation for Laravel.

2.0k15.9M104](/packages/bensampo-laravel-enum)[swaggest/json-schema

High definition PHP structures with JSON-schema based validation

48612.5M73](/packages/swaggest-json-schema)[stevebauman/purify

An HTML Purifier / Sanitizer for Laravel

5325.6M19](/packages/stevebauman-purify)[ashallendesign/laravel-config-validator

A package for validating your Laravel app's config.

217905.3k5](/packages/ashallendesign-laravel-config-validator)[crazybooot/base64-validation

Laravel validators for base64 encoded files

1341.9M8](/packages/crazybooot-base64-validation)

PHPackages © 2026

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