Skip to content
alexpr07Public

About

CSS that knows your page: variables, nesting, $[index], :seen, :stuck, :overflowing, :contains(). No build step.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CSS Post Processor

CSS that knows your page. CSS Post Processor (css-pp) is a 10.4 KB, dependency-free script that extends CSS in the browser. It adds variables with JavaScript, nesting, per-element values that work even inside url(), and the selectors native CSS still lacks: :seen, :in-view, :stuck, :overflowing, :contains() and numeric attribute comparisons.

No build step. Ordinary CSS passes through unchanged.

Website and full documentation: csspp.dev

/* a different image for every slide, any number of slides */
.slider > div { background-image: url(/img/slide-$[index].jpg); }

/* fade cards in the first time they scroll into view */
.card:not(:seen) { opacity: 0; translate: 0 2rem; }

/* shadow only while the sticky header is actually stuck */
header:stuck { box-shadow: 0 2px 12px rgb(0 0 0 / .2); }

/* "Read more" only when the excerpt is really truncated */
.post:has(.excerpt:overflowing) .more { display: inline; }

/* active nav link, header that hides on the way down */
nav a:current { font-weight: 700; }
html:scrolling-down header { translate: 0 -100%; }

/* style by text and by numbers */
.product:has(.badge:contains("sold out" i)) { opacity: .5; }
.product:has([data-stock<5]) .low-stock { display: block; }

Install

<script src="https://cdn.jsdelivr.net/npm/css-post-processor@3.2.1/dist/css-pp.min.js"
        integrity="sha384-T1bI8VjOVeN7L8QkEg/v3zEkxyzVreA9qchbx+0gd9tOItYJlbVFgRiodhzslST/" crossorigin="anonymous"></script>
<script>
  css.defaults.debug = 0;
  css.open('/css/site.css');   // fetch, process and inject your stylesheet
</script>

or npm install css-post-processor and include dist/css-pp.min.js. Process inline styles with css.open('#id').

Features

Feature Syntax Docs
Seen / in view :seen, :seen(30%), :in-view, :in-view(50%) State selectors
Sticky element is pinned :stuck State selectors
Content is truncated :overflowing State selectors
Select by text :contains("text"), :contains("text" i) Content selectors
Compare numbers [data-x<5], [data-x>=100] Content selectors
Active link, scroll state :current, :scrolled(80px), :scrolling-down, :scroll-end, :target-in-view Scroll & navigation
Images, layout, forms img:loaded, img:broken, :wrapped, :filled, :dirty, :offline, :idle(30s) Media, layout & forms
Per-element values $[index], $[random(1,5)], $[attr(data-bg)], $[count], $[year], even inside url() Values
Pseudo-elements from JS css.on('click', '.chip::after', fn), css.pseudo(el, '::after').set('color', 'red'), .chip::after:hover Pseudo-elements
Fit text, equal heights font-size: fit(24px, 120px), height: same Layout helpers
Variables, mixins, JavaScript $brand{#0ea5e9}, $m(1px){border:&a solid}, $half{css.vars.w()/2} Variables
Responsive variables $vw!{css.vars.w()}, recalculated on resize Variables
Nesting &:hover, .dark &, &-title, @media inside rules Nesting

Every selector compiles to an attribute selector with the same specificity, updates live as the DOM changes, and works inside native :has().

Size and support

29.5 KB minified, 10.4 KB gzipped. The core is ES5 and runs in every browser. The state and content selectors use IntersectionObserver, MutationObserver and ResizeObserver, which are available in all evergreen browsers. A 74 KB stylesheet with variables and nesting compiles in about 9 ms on a desktop.

See how it works, performance and limitations, including Content Security Policy notes.

License

MIT © 2016–2026 Alex Bobrov

About

CSS that knows your page: variables, nesting, $[index], :seen, :stuck, :overflowing, :contains(). No build step.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors