npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@hyperdivision/czz

v0.6.2

Published

ZZZ CSS

Downloads

10

Readme

CZZ

ZZZ CSS

Usage

var CZZ = require('CZZ')

var className = CZZ`
/* CZZ is a CSS-in-JS dialect inspired by BSS */
// Extensions include single line comments

width: 100px; // And you can define styles right here and they will be wrapped

/* You can also use shorthands. Emmet-style shorthands are built-in, and if
 * naked units are found, and pixel support can be detected, they will be
 * transformed. Eg the next line becomes 'height: 100px'
 */
h 100

// Fully qualified rules are not expanded by the preprocessor (but units are)
// ie. name, colon, value, semi-colon. Otherwise this rule would be interpreted
// as "display" and not "d"
d: path("M 10,30 \
         A 20,20 0,0,1 50,30 \
         A 20,20 0,0,1 90,30 \
         Q 90,60 50,90 \
         Q 10,60 10,30 z");

// Substyles are automagically nested, ie this becomes '.RANDOM_CLASS .child'
.child {
  // The & operator can be used to insert the parent selector, here yielding
  // .RANDOM_CLASS .child.compound-child
  &.compound-child {

  }
}

// naked pseudo classes are also handled, ie '.RANDOM_CLASS .foo:hover'
:hover {
  c red
}

// You can also define inline animations. Here we animate the opacity
animation 1200ms {
  from { o 0 }
  to { o 1 }
}

// Media queries can also be nested at any spot
@media only screen and (max-width: 600px) {
  w 100%
}

Will generate something similar to:

@keyframes czz-ani-sm8y00rd71 {
  from {
    opacity: 0;
  }

  to {
    opacity: 0;
  }
}

.czz-np4ddc2dsth {
  width: 100px;
  height: 100px;
  animation: 1200mx czz-ani-sm8y00rd71;
}

.czz-np4ddc2dsth .child.compound-child {}

.czz-np4ddc2dsth:hover {
  color: red;
}

@media only screen and (max-width: 600px) {
  .czz-np4ddc2dsth {
    width: 100%;
  }
}

API

const styles = CZZ`...css...`

CZZ composable styles. Suppots:

  • Random, namespaced class name for top-level CSS rules, eg. width: 100px; -> .parent { width: 100px; }

  • Nesting with naked selectors or &

    • Classes are nested with space between, eg. .child -> .parent .child
    • Pseudo classes are nested directly, eg. :hover -> .parent:hover
    • Multiple selectors are split, eg. .child, :hover -> .parent .child, .parent:hover
    • & marks parent selector placement, eg. .foo & -> .foo .parent
  • Shorthands through transforms, eg. w 100 -> width: 100px

  • Skip shorthands with full css rule, eg. d: ... -> d: ... (noop)

  • Automatic unit insertion, eg. w 100 -> width: 100px (notice px)

  • Multiline (/* ... */) and single-line (// ...) comments

  • Inline animations, eg. animation 125ms ease { ...keyframes... }

  • Inline media queries, which understand nesting

  • Composition using compound CSS selectors.

Rules are automatically injected into a <head> style tag the first time they're seen. Rules are cached based on string equality to avoid leaking memory when rerendering styles.

See below API for the function returned.

const composed = styles`...css...`

Compose with new rules, meaning you can "inherit" namespaced rules.

const selector = styles.toString()

Returns the generated selector

const classList = styles.classList

Array of class names that are composed together. Can be added with elm.classList.add(...styles.classList)

const css = styles.css

String containing the generated CSS

const styles = CZZ.global`...css...`

Create a global style. Naked classes here are not automatically nested, hence you can create rules for top-level classes and elements. Stray rules are nested under a .czz-global-* class, which is contained in the styles function. Otherwise follows the rules of plain CZZ

CZZ.transforms

A global array of transformation functions. When parsing unknown properties of CZZ, each transformation is tried in succession until either a set of rules are returned or the list is exhausted. You can .push or .unshift the array as you want, just be aware that this must be done before any styles are applied and that the array is global.

By default the list contains Emmet style CSS shorthands.

See below for details on how to make Custom transforms.

Automatic unit insertion

px will be applied as the default unit where possible. However units will not be applied to numbers between ( ), unless it is translate(…) or rotate(…) (in the ladder case the unit will be deg). This is to avoid rgb(100, 100, 100) from becoming rgb(100px, 100px, 100px).

Pixel support is detected by taking the CSS property name and applying a 1px rule, and if this can be read back out, it will be flagged as supporting pixels. Hardcoded exceptions exist in lib/is-pixel.js

Custom transforms

Custom transforms can be passed as functions taking arguments property and value. Any non-falsy return will be applied as the transform and no other transforms will be attempted. To apply a transform you must return an array of resolved rules. The values will have the above "Automatic unit insertion" applied.

// Tailwind style 'truncate', example `truncate ellipsis`
module.exports = (property, value) => property === 'truncate' && [
  ['overflow', 'hidden'],
  ['text-overflow', value],
  ['white-space', 'nowrap']
]

// Tailwind style 'px' (padding along the x axis), example `px 1rem`
module.exports = (property, value) => property === 'px' && [
  ['padding-left', value],
  ['padding-right', value]
]

Install

npm install czz

Credits

CZZ is strongly inspired by BSS but with small modifications, and is more strict in it's parsing.

License

ISC