{"id":21502746,"url":"https://github.com/fuzetsu/zaftig","last_synced_at":"2025-07-15T23:30:55.253Z","repository":{"id":34650772,"uuid":"182198787","full_name":"fuzetsu/zaftig","owner":"fuzetsu","description":"~2kB css in js: z`display flex` // .zjsdkk43-1","archived":false,"fork":false,"pushed_at":"2024-06-17T21:13:27.000Z","size":256,"stargazers_count":15,"open_issues_count":8,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-11-19T16:03:32.437Z","etag":null,"topics":["css","css-in-js","hyperscript","jsx","vdom"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fuzetsu.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-19T03:59:45.000Z","updated_at":"2021-03-10T02:06:51.000Z","dependencies_parsed_at":"2023-01-15T08:21:54.783Z","dependency_job_id":null,"html_url":"https://github.com/fuzetsu/zaftig","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fuzetsu%2Fzaftig","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fuzetsu%2Fzaftig/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fuzetsu%2Fzaftig/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fuzetsu%2Fzaftig/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fuzetsu","download_url":"https://codeload.github.com/fuzetsu/zaftig/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226077471,"owners_count":17570164,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css","css-in-js","hyperscript","jsx","vdom"],"created_at":"2024-11-23T18:17:32.458Z","updated_at":"2024-11-23T18:17:33.095Z","avatar_url":"https://github.com/fuzetsu.png","language":"JavaScript","readme":"# Zaftig [![npm](https://img.shields.io/npm/v/zaftig.svg)](https://www.npmjs.com/package/zaftig) [![size](https://img.shields.io/bundlephobia/minzip/zaftig)](https://unpkg.com/zaftig@latest/dist/zaftig.min.js)\n\nZaftig efficiently parses styles, generates a classname for them and inserts them a into a stylesheet in the head of the document.\n\nPassing the same style string will return the same classname.\n\n```js\nz`display flex` // .zjsdkk43-1\nz`display flex` // .zjsdkk43-1\n```\n\n## Highlights\n\n- 💸 Quick and lightweight\n- 🙇 User defined helper functions `z.helper({})`\n- 💯 Simplified CSS syntax with nested selector support `` z`:hover { c green }` ``\n- 🅰️ Initial based CSS property shorthands _e.g. bc == background-color or d == display_\n- ⚙️ Basic automatic vendor prefixing for: Chrome, Safari, Firefox, Edge, Opera (webkit)\n\nExample:\n\n```jsx\n// works just as well with React and other libraries/frameworks\nimport { render, h } from 'preact'\nimport z from 'zaftig'\n\nz.setDot(false)\n\nz.global`\n  $btn-color #4444dd\n  font-family sans-serif\n  font-size 14\n  margin 10\n`\n\nconst btn = z`\n  border none\n  padding 0.75rem\n  line-height 1.2rem\n  color $btn-color\n  border 0.5 solid $btn-color\n  background-color white\n  font-size 16\n  cursor pointer\n  transition transform 100ms\n  outline none\n\n  :active { transform scale(0.9) }\n  \u0026.primary { bc $btn-color; c white }\n  \u0026.rounded { border-radius 4 }\n`\n\nconst btnGroup = z`.${btn} { margin 5 }`\nconst btnWarning = btn.z`$btn-color #ee5555`\nconst btnSuccess = btn.z`$btn-color green`\n\nconst App = () =\u003e (\n  \u003cmain className={btnGroup}\u003e\n    \u003cbutton className={btn.concat('primary', 'rounded')}\u003ePrimary\u003c/button\u003e\n    \u003cbutton className={btnWarning.concat('rounded')}\u003eWarning\u003c/button\u003e\n    \u003cbutton className={btnSuccess}\u003eSuccess\u003c/button\u003e\n    \u003cbutton className={btnSuccess.concat('primary rounded')}\u003eSuccess + Primary\u003c/button\u003e\n  \u003c/main\u003e\n)\n\nrender(\u003cApp /\u003e, document.body)\n```\n\n[![example](/docs/img/example.png)][example-playground]\n\n[playground][example-playground]\n\n## Usage\n\nModule:\n\n```js\nimport z from 'zaftig'\n\nz.setDot(false) // if you're using React\n\nz`color green; background red`\n```\n\nScript:\n\n```html\n\u003c!-- uses zaftig.es5.min.js --\u003e\n\u003cscript src=\"https://unpkg.com/zaftig\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  z.setDot(false) // if you're using React\n\n  z`color green; background red`\n\u003c/script\u003e\n```\n\nOr download the script and use it locally.\n\n[You can see all the options here.](https://unpkg.com/zaftig@latest/dist/)\n\n## Plugins and Tools\n\n- [Highlight CSS Lean Strings](https://marketplace.visualstudio.com/items?itemName=fuzetsu.highlight-css-lean-strings\u0026ssr=false#overview): a vscode plugin that will add syntax highlighting for Zaftig style strings in your JS code\n- [Zaftig Tailwind](https://github.com/fuzetsu/zaftig-tailwind): a collection of helpers based on [Tailwind css](https://tailwindcss.com)\n\n## API\n\nQuick links: [`z`](#css) ~~ [`z.setDebug`](#set-debug) ~~ [`z.setDot`](#set-dot) ~~ [`z.global`](#global) ~~ [`z.style`](#style) ~~ [`z.concat`](#concat) ~~ [`z.anim`](#anim) ~~ [`z.helper`](#helper) ~~ [`z.getSheet`](#get-sheet) ~~ [`z.new`](#new)\n\n\u003chr\u003e\n\n\u003ca name=\"css\"\u003e\u003c/a\u003e\n\n### `` z`\u003cStyleString\u003e` ``\n\nGenerates a `className` for the given `StyleString` and inserts it into a stylesheet in the head of the document.\n\nIt returns a `Style` object `{ class, className, concat, z }`.\n\n`.concat` allows you to combine the current className with others. [See `z.concat`](#concat).\n\n`.z` lets you extend/chain another `StyleString`, it calls `.concat` under the hood and is equivalent to `` z`...`.concat(z`...`) ``\n\n```js\nconst white = z`color white` // z1234-1\nconst whiteAndBlack = white.z`background-color black` // z1234-1 z1234-2\nconst extended = whiteAndBlack.concat(z`font-size 20px`, 'test') // z1234-1 z1234-2 z1234-3 test\n```\n\nWhen `.toString()` is called on a `Style` object the `className` will be returned.\n\nWhen `.valueOf()` is called it will return the `className` with a dot prefixed. This allows you to directly concatenate style objects to tag names when using a hyperscript helper like mithril offers:\n\n```js\nm('h1' + z`margin auto`) ==\u003e m('h1.zfwe983')\n```\n\nExample expressions:\n\n```js\nz`color green`\nz`color green; background-color orange`\nz`\n  color green\n  background-color orange\n  :focus {\n    margin 20px\n    ::placeholder { c orange }\n  }\n  \u003e span { p 10px }\n`\nz`c green;bc orange`\n```\n\nStyles are separated by `;` or `\\n`.\n\n`sel { /* rules */ }` creates a nested style. Use `\u0026` within the selector to reference the parent selector similar to how [Less](http://lesscss.org/) works.\n\nThere are a couple of special properties that can be used within a `StyleString`.\n\n`$name` will prepend the given string to the generated class name to make it easier to read the DOM:\n\n```js\nz`\n  $name button\n  border none\n`\n// generated classname will look something like: 'button-z2djkf2342-1'\n```\n\n`$compose` will make `z` generate a list of classnames rather than just the generated one:\n\n```js\nz`\n  $compose btn btn-primary\n  border none\n`\n// .class will output something like: 'btn btn-primary z2djkf2342-1'\n```\n\nThis allows you to easily combine zaftig generated classes with external css classes that you've manually written or that are provided by a css framework/library.\n\n#### CSS variable handling:\n\nYou can create/reference css variables using the `$` syntax. The normal css syntax using `--` and `var()` also works.\n\n```js\nz.global`\n  $bg-color black\n  $fg-color white\n  $font-size 16px\n`\n\nz`\n  color $fg-color\n  background-color $bg-color\n  font-size $font-size\n`\n```\n\n```css\n/* generated css */\n\n:root {\n  --bg-color: black;\n  --fg-color: white;\n  --font-size: 16px;\n}\n\n.z2djkf2342-1 {\n  color: var(--fg-color);\n  background-color: var(--bg-color);\n  font-size: var(--font-size);\n}\n```\n\n#### Automatic px:\n\nZaftig will automatically append `px` to any numeric value provided to a css property that accepts `px` values.\n\n```js\nz`\n  margin 10\n  padding 100\n  width 5\n  height 50\n  box-shadow 0 2 4 0 rgba(0, 0, 0, 0.1)\n  opacity 0.5\n`\n```\n\n```css\n/* generated css */\n\n.z2djkf2342-1 {\n  margin: 10px;\n  padding: 100px;\n  width: 5px;\n  height: 50px;\n  box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);\n  opacity: 0.5;\n}\n```\n\nYou can specify `px` manually if you prefer to, but `zaftig` will add it for you if you don't.\n\n\u003chr\u003e\n\n\u003ca name=\"set-debug\"\u003e\u003c/a\u003e\n\n### `z.setDebug(bool)`\n\nEnable/disable debug mode.\n\nIn debug mode Zaftig will insert styles using `textContent` and will log to the console when an unknown css property is encountered.\n\n`textContent` is much less efficient than the non debug CSSOM method, but it allows you to modify the styles using chrome dev tools.\n\n**NOTE:** make sure to call `setDebug` before inserting any styles\n\n\u003chr\u003e\n\n\u003ca name=\"set-dot\"\u003e\u003c/a\u003e\n\n### `z.setDot(bool)`\n\nControls how [`Style`](#css) objects behave when `valueOf()` is invoked.\n\nThe default for `dot` is `true`, meaning that a dot will be prepended to classNames, this is useful when using a hyperscript helper such as [microh](https://github.com/fuzetsu/microh) or [Mithril's](https://github.com/MithrilJS/mithril.js) `m` function.\n\nUnder normal circumstances this should not interfere with usage of zaftig, but depending on how some libraries process component props you may want to disable the dot.\n\n\u003chr\u003e\n\n\u003ca name=\"global\"\u003e\u003c/a\u003e\n\n### `` z.global`\u003cStyleString\u003e` ``\n\nAppends global styles. Multiple calls with the same string will result in the style being appended multiple times.\n\n```js\nz.global`\n  html, body {\n    font-family sans-serif\n    margin 0\n  }\n`\n```\n\n\u003chr\u003e\n\n\u003ca name=\"style\"\u003e\u003c/a\u003e\n\n### `` z.style`\u003cStyleString\u003e` ``\n\nParses given style string and returns string of css rules. Useful for styles that change frequently to prevent generating too many classNames.\nResulting string can be assigned to the style attribute of a DOM element.\n\n```js\nz.style`color ${fgColor};background-color ${bgColor}`\n\n// returns\n;('color: #444; background-color: #fff;')\n```\n\nNested selectors will be ignored, only simple styles will be returned.\n\n\u003chr\u003e\n\n\u003ca name=\"concat\"\u003e\u003c/a\u003e\n\n### `z.concat(...(string | Style | Falsy))`\n\nProcesses all the given arguments into a final `className` wrapped in a `Style` object for further chaining.\n\nFalsy arguments are ignored which means arguments can be conditionally included.\n\n```js\nz.concat('hello', cond \u0026\u0026 'world') // 'hello' or 'hello world' depending on cond\n\n// you can use either strings or zaftig styles\nz.concat('btn btn-large', z`c green`) // 'btn btn-large z1234-1'\n\n// concat can be used statically\nz.concat('one', 'two') // 'one two'\n\n// or chained of an existing style\nz`c green`.concat('one', 'two') // 'z1234-1 one two'\n\n// you can continue chaining after calling concat\nz.concat('one').concat('two').concat('three').z`c green` // 'one two three z1234-1'\n```\n\n\u003chr\u003e\n\n\u003ca name=\"anim\"\u003e\u003c/a\u003e\n\n### `` z.anim`\u003cStyleString\u003e` ``\n\nGenerates an `@keyframes` for the given `StyleString`. It returns the generated name.\n\n```js\nconst grow = z.anim`\n  0% { scale(0.2) }\n  100% { scale(1) }\n`\n// then to use it\nz`animation ${grow} 1s ease`\n```\n\n\u003chr\u003e\n\n\u003ca name=\"helper\"\u003e\u003c/a\u003e\n\n### `z.helper({ helperName: StyleString | Function, ... })`\n\nRegister helpers functions to be called from style strings.\n\nA helper can be a `StyleString` or a function that returns a `StyleString`.\n\nIf the helper is a function it will receive arguments, as seen in the `size` example below.\nIf it is a `StyleString` it will have arguments appended to it.\n\n```js\nz.helper({\n  mx: x =\u003e `margin-left ${x}; margin-right ${x}`,\n  size: (h, w) =\u003e `h ${h}; w ${w}`,\n  shadow: 'box-shadow 0 2 4 2 rgba(0,0,0,0.5)',\n  smooth: 'transition' // since args are appended, this can act as an alias\n})\n\nz`\n  mx 10\n  size 50 100\n  shadow\n  smooth color 1s\n`\n```\n\n```css\n/* generated css */\n\n.z2djkf2342-1 {\n  margin-left: 10px;\n  margin-right: 10px;\n  height: 50px;\n  width: 100px;\n  box-shadow: 0px 2px 4px 2px rgba(0, 0, 0, 0.5);\n}\n```\n\nString based helpers will have any arguments passed automatically appended. This allows you to easily create your own css property shorthands.\n\n```js\nz.helper({\n  bo: 'border',\n  tra: 'transition'\n})\n\nz`\n  bo 4 solid red\n  tra 500ms\n`\n```\n\n```css\n/* generated css */\n\n.zx5cc6j6obc9-1 {\n  border: 4px solid red;\n  transition: 500ms;\n}\n```\n\nHelpers can also be used in selectors, mainly useful for media queries.\n\n```js\nconst breakpoints = { sm: '640px', md: '768px', lg: '1024px', xl: '1280px' }\n\nz.helper({\n  // can be function with arguments like normal helpers\n  '@med': x =\u003e `@media (min-width: ${breakpoints[x]})`,\n  // or simply a string\n  '@lg': '@media (min-width: 1024px)'\n})\n\nz`\n  c blue\n  @med md { c orange }\n  @lg { c red }\n`\n```\n\n```css\n/* generated css */\n.z2djkf2342-1 {\n  color: blue;\n}\n\n@media (min-width: 768px) {\n  .z2djkf2342-1 {\n    color: orange;\n  }\n}\n\n@media (min-width: 1024px) {\n  .z2djkf2342-1 {\n    color: red;\n  }\n}\n```\n\n\u003chr\u003e\n\n\u003ca name=\"get-sheet\"\u003e\u003c/a\u003e\n\n### `z.getSheet()`\n\nReturns the DOM node representing the stylesheet.\n\nYou can read the stylesheet from it in a couple ways depending on the whether you're in debug mode or not:\n\n```js\n// in debug mode you can look for the stylesheet in document.head in DOM or like this:\nz.getSheet().textContent\n// in prod mode you can use the following code to get the stylesheet:\n[...z.getSheet().sheet.cssRules].map(x =\u003e x.cssText).join('\\n')\n```\n\n\u003chr\u003e\n\n\u003ca name=\"new\"\u003e\u003c/a\u003e\n\n### `z.new(config)`\n\nCreates a new instance of zaftig, with a separate style element, helpers and rule/parser cache.\n\nThe new instance will have all the same methods as the default one.\n\n`config` is an optional object parameter that looks something like this:\n\n```js\nconst newZ = z.new({\n  // if you pass a style elem, you need to append it to the doc yourself\n  // if you don't pass one then zaftig will create and append one for you\n  style: document.head.appendChild(document.createElement('style')),\n\n  // override the prefix for all classes generated by zaftig\n  // a random one will be generated by default\n  id: 'custom-id',\n\n  // preload the instance with some helpers\n  // defults to {}, add more with z.helper()\n  helpers: { mx: x =\u003e `ml ${x}; mr ${x}` },\n\n  // overrides auto-px behavior, if property accepts px, then automatically\n  // this unit to numbers\n  unit: 'rem',\n\n  // debug flag, default is false\n  debug: true,\n\n  // whether or not to add dot to className when valueOf() is called, default is true\n  dot: true\n})\n```\n\nCreating a new instance is useful when you want to you ensure you get a private/non global version of zaftig, or to render styles into a shadow DOM.\n\n## Credits\n\nHeavily inspired by [bss](https://github.com/porsager/bss) by [Rasmus Porsager](https://github.com/porsager).\n\n[example-playground]: https://codesandbox.io/s/zaftig-readme-example-6jlb9?file=/src/index.js\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuzetsu%2Fzaftig","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffuzetsu%2Fzaftig","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuzetsu%2Fzaftig/lists"}