{"id":23274257,"url":"https://github.com/luncheon/isaaccss","last_synced_at":"2026-04-20T03:02:31.356Z","repository":{"id":58476557,"uuid":"527828809","full_name":"luncheon/isaaccss","owner":"luncheon","description":"Inline-Style-as-a-Class CSS engine","archived":false,"fork":false,"pushed_at":"2022-09-20T06:16:00.000Z","size":6469,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-26T01:14:47.017Z","etag":null,"topics":["atomic-css","css","css-framework","css-generator","css-in-js","css-utilities","inline-css","inline-styles","open-props","postcss","tailwindcss","utility-classes","windicss"],"latest_commit_sha":null,"homepage":"https://luncheon.github.io/isaaccss/playground/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"wtfpl","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/luncheon.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2022-08-23T04:13:20.000Z","updated_at":"2023-08-24T03:10:56.000Z","dependencies_parsed_at":"2022-09-21T13:52:03.635Z","dependency_job_id":null,"html_url":"https://github.com/luncheon/isaaccss","commit_stats":null,"previous_names":[],"tags_count":23,"template":false,"template_full_name":null,"purl":"pkg:github/luncheon/isaaccss","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luncheon%2Fisaaccss","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luncheon%2Fisaaccss/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luncheon%2Fisaaccss/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luncheon%2Fisaaccss/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/luncheon","download_url":"https://codeload.github.com/luncheon/isaaccss/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luncheon%2Fisaaccss/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32031070,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T00:18:06.643Z","status":"online","status_checked_at":"2026-04-20T02:00:06.527Z","response_time":94,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["atomic-css","css","css-framework","css-generator","css-in-js","css-utilities","inline-css","inline-styles","open-props","postcss","tailwindcss","utility-classes","windicss"],"created_at":"2024-12-19T20:12:41.231Z","updated_at":"2026-04-20T03:02:31.326Z","avatar_url":"https://github.com/luncheon.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# isaaccss: Inline-Style-as-a-Class CSS engine\n\nAn atomic CSS DSL like inline style.\n\n\u003c!-- prettier-ignore --\u003e\n```jsx\nimport { is } from \"isaaccss\";\n\nconst SubmitButton = ({ variant }: { variant: 'primary' | 'secondary' }) =\u003e (\n  \u003cbutton class={is`\n    background:hsl(var(--H),var(--S),var(--L)) ${variant === \"secondary\" ? is`--H:30` : is`--H:210`}\n    --S:100% --L:50% :hover/--L:60% :active/--L:40%*\n    border:3px_solid_hsl(var(--H),var(--S),80%) border-radius:8px color:white\n    padding:4px_8px @width\u003e=768px/padding:8px_16px @hover:hover/:hover/scale:1.1\n  `}\u003e\n    Submit\n  \u003c/button\u003e\n);\n```\n\nOr using some short aliases:\n\n\u003c!-- prettier-ignore --\u003e\n```jsx\nimport { is } from \"isaaccss\";\n\nconst SubmitButton = ({ variant }: { variant: 'primary' | 'secondary' }) =\u003e (\n  \u003cbutton class={is`\n    bg:hsl($H,$S,$L) ${variant === \"secondary\" ? is`--H:30` : is`--H:210`}\n    --S:100% --L:50% :hover/--L:60% :active/--L:40%* \n    b:3px_solid_hsl($H,$S,80%) b-radius:8px c:white\n    p:4px_8px @w\u003e=768px/p:8px_16px @hover:hover/:hover/scale:1.1\n  `}\u003e\n    Submit\n  \u003c/button\u003e\n);\n```\n\n[Playground](https://luncheon.github.io/isaaccss/playground/)\n\n## Installation\n\n```\nnpm i -D isaaccss\n```\n\n## Usage\n\nImport `is` from `\"isaaccss\"` and write styles in `is`-tagged template.\n\n```js\nimport { is } from \"isaaccss\";\n\ndocument.body.className = is`m:0 @screen\u0026w\u003e=640px/m:1rem`;\n```\n\nThe above code with default config generates the following JS and CSS:\n\n```js\ndocument.body.className = `#a #b`;\n```\n\n```css\n.\\#a:not(#\\ ) {\n  margin: 0;\n}\n\n@media screen and (width\u003e=640px) {\n  .\\#b:not(#\\ ) {\n    margin: 1rem;\n  }\n}\n```\n\n- `#` of `#a`, `#b`: prefix to avoid conflicts with other libraries and your CSS. Customizable.\n- `:not(#\\ )`: selector to increase ID-specificity. Ensures greater specificity than other libraries or your CSS.\n\n## Syntax\n\n```\n[@media/][@^container/][selectors/]property:value[!][;property:value[!]...][?][*[*...]]\n ~~~~~~~  ~~~~~~~~~~~~  ~~~~~~~~~~ ~~~~~~~~ ~~~~~ ~  ~~~~~~~~~~~~~~~~~~~~~  ~  ~~~~~~~\n   (1)        (2)           (3)      (4)     (5) (6)          (7)          (8)   (9)\n```\n\n1. Optional `@media/` indicates [media queries](https://developer.mozilla.org/docs/Web/CSS/Media_Queries/Using_media_queries)\n   - `@foo/d:none` generates `@media foo { .\\#a { display: none } }`  \n     (`.\\@foo\\/d\\:none` is compressed into `.\\#a`)\n   - Tokens are parenthesized where necessary  \n     e.g. `@screen\u0026w\u003e=640px/m:0` -\u003e `@media screen and (width \u003e= 640px) { .\\#a { margin: 0 } }`\n2. Optional `@^container/` indicates [container queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Container_Queries)\n   - `@^w\u003e=200/m:1rem` generates `@container (w\u003e=200) { .\\#a { margin:1rem } }`\n   - `@^card(w\u003e=200)/m-l:1rem` generates `@container card (w\u003e=200) { .\\#a { margin-left: 1rem } }`\n3. Optional `selectors/` indicates additional selectors\n   - [Pseudo-classes](https://developer.mozilla.org/docs/Web/CSS/Pseudo-classes)  \n     e.g. `:hover/`, `:has(\u003e:checked)/`\n   - [Pseudo-elements](https://developer.mozilla.org/docs/Web/CSS/Pseudo-elements)  \n     e.g. `::before/`, `::part(foo)/`\n   - [Child combinator](https://developer.mozilla.org/docs/Web/CSS/Child_combinator)  \n     e.g. `\u003ediv/`\n   - [Adjacent sibling combinator](https://developer.mozilla.org/docs/Web/CSS/Adjacent_sibling_combinator)  \n     e.g. `+div/`\n   - [General sibling combinator](https://developer.mozilla.org/docs/Web/CSS/General_sibling_combinator)  \n     e.g. `~div/`\n   - Combination of the above  \n     e.g. `:hover\u003einput+label::before/`\n   - If there are ampersands `\u0026`, they becomes that class  \n     e.g. `\u0026+\u0026/m-l:1rem` -\u003e `.\\\u0026\\+\\\u0026 + .\\\u0026\\+\\\u0026 { margin-left: 1rem }`\n4. Required `property` indicates the property name\n   - Must be one of the [known properties](https://github.com/known-css/known-css-properties/blob/master/data/all.json) or a [custom property](https://developer.mozilla.org/docs/Web/CSS/--*)\n5. Required `value` indicates the property value\n   - `$bar` will be replaced with `var(--bar)`\n     - Custom property set libraries, such as [Open Props](https://open-props.style/), can help with design themes\n6. Optional `!` indicates [`!important`](https://developer.mozilla.org/en-US/docs/Web/CSS/important)\n7. Multiple `property:value[!]` can be specified, delimited by semicolons `;`\n8. Optional trailing `?` generates unnamed [`@layer{}`](https://developer.mozilla.org/docs/Web/CSS/@layer)\n   - For example, add `?` to the components in a component library, so that applications using it can override the properties\n9. Optional trailing `*` increases ID-[specificity](https://developer.mozilla.org/docs/Web/CSS/Specificity), more than one can be specified\n   - For example, add `*` to the preferred style between `:hover` and `:active`\n\n- An underscore `_` will be replaced with a whitespace ` ` and can be escaped with a backslash (`\\_` will be replaced with `_`)\n\n## Setup\n\n### [esbuild](https://esbuild.github.io/)\n\n```js\nimport esbuild from \"esbuild\";\nimport isaaccss from \"isaaccss/esbuild\";\n\nesbuild.build({\n  entryPoints: [\"src/index.ts\"],\n  outdir: \"dist\",\n  bundle: true,\n  // Inject `isaaccss.inject`.\n  inject: [isaaccss.inject],\n  plugins: [\n    isaaccss.plugin({\n      // Optional filename filter. Default is following.\n      filter: /\\.[cm][jt]x?$/,\n\n      // Optional isaaccss config. See `Configuration Example` section below.\n      pretty: true,\n      compress: { prefix: \"~\" },\n      aliases: [],\n      postcss: { plugins: [] },\n    }),\n  ],\n});\n```\n\n### [Rollup](https://rollupjs.org/)\n\n```js\n// rollup.config.js\nimport isaaccss from \"isaaccss/rollup\";\n\n/** @type {import(\"rollup\").RollupOptions} */\nexport default {\n  input: \"src/index.js\",\n  output: { file: \"dist/index.js\" },\n  plugins: [\n    isaaccss({\n      // Optional include filter. By default, all bundled scripts are included.\n      include: [\"**/*.js\"],\n\n      // Optional exclude filter. By default, `**/node_modules/**` are excluded.\n      exclude: [\"**/node_modules/**\"],\n\n      // Optional output filename.\n      // Default is the output script filename with extension \".css\".\n      output: \"dist/index.css\",\n\n      // Optional isaaccss config. See `Configuration Example` section below.\n      pretty: true,\n      compress: { prefix: \"~\" },\n      aliases: [],\n      postcss: { plugins: [] },\n    }),\n  ],\n};\n```\n\nWhen you want to merge other CSS files with isaaccss CSS, use [`rollup-plugin-import-css`](https://github.com/jleeson/rollup-plugin-import-css) instead of [`rollup-plugin-css-only`](https://github.com/thgh/rollup-plugin-css-only).\n\n```js\n// rollup.config.js\nimport css from \"rollup-plugin-import-css\";\nimport isaaccss from \"isaaccss/rollup\";\n\n/** @type {import(\"rollup\").RollupOptions} */\nexport default {\n  input: \"src/index.js\",\n  output: { file: \"dist/index.js\" },\n  plugins: [css(), isaaccss()],\n};\n```\n\n### [Vite](https://vitejs.dev/)\n\nClass names are not compressed in Vite dev server, but in Vite build.\n\n```js\n// vite.config.js\nimport isaaccssPlugin from \"isaaccss/vite\";\n\n/** @type {import(\"vite\").UserConfig} */\nexport default {\n  plugins: [\n    isaaccssPlugin({\n      // Options are same as for Rollup isaaccss plugin above.\n    }),\n  ],\n};\n```\n\n## Configuration Example\n\n```js\nimport { defaultAliases } from \"isaaccss/aliases\";\nimport OpenProps from \"open-props\";\nimport postcssJitProps from \"postcss-jit-props\";\n\nexport default {\n  // Whether to pretty-print. Default is `false`.\n  pretty: true,\n\n  // Class name compression setting in boolean or `{ prefix: string }`. Pass `false` to turn off.\n  // Default is `{ prefix: \"#\" }`; class names are \"#a\", \"#b\", ..., \"#aa\", \"#ab\", ...\n  compress: { prefix: \"~\" },\n\n  // Aliases. If specified, the default aliases are removed.\n  aliases: [\n    // If you want to extend the default, pass the `defaultAliases` imported from \"isaaccss\".\n    defaultAliases,\n\n    // Custom aliases. For example:\n    {\n      // Alias format of `media`, `container` and `selector` is one of the following:\n      // - { \"search\": replacementString }\n      // - [/pattern/g, replacementStringOrFunction]\n      // - Array of the above\n      media: {\n        dark: \"prefers-color-scheme:dark\",\n        light: \"prefers-color-scheme:light\",\n        sm: \"640px\", // use breakpoints like `@w\u003csm/d:none`\n        md: \"768px\",\n      },\n      container: {},\n      selector: {\n        \"::a\": \"::after\",\n        \"::b\": \"::before\",\n        \":f\": \":focus\",\n        \":h\": \":hover\",\n      },\n\n      // Alias format of `property` is one of the following:\n      // - { \"search\": replacementStringOrStringArray }\n      // - [/pattern/g, replacementStringOrStringArray]\n      // - Array of the above\n      property: {\n        items: \"align-items\",\n        justify: \"justify-content\",\n      },\n\n      // Alias format of `value` is one of the following:\n      // - [propertyNameOrPattern, { \"search\": replacementString }] or\n      // - [propertyNameOrPattern, [/pattern/g, replacementStringOrFunction]]\n      // - Array of the above\n      value: [\n        [\n          \"box-shadow\",\n          {\n            sm: \"0 1px 2px hsla($shadow-hsl / 0.1)\",\n            md: \"0 1px 2px hsla($shadow-hsl / 0.1),0 3px 6px hsla($shadow-hsl / 0.1)\",\n          },\n        ],\n        [\n          // an example of rem-based pixel unit\n          // `m:[1]`-\u003e{margin:.0625rem} `m-l:[16]`-\u003e{margin-left:1rem}\n          /^margin|^padding|^font-size$/,\n          [/\\[(-?\\d*\\.?\\d+)\\]/g, (_, $1) =\u003e `${+$1 / 16}rem`.replace(/^0\\./, \".\")],\n        ],\n      ],\n    },\n  ],\n\n  // Optional PostCSS config. The only field is `plugins`.\n  // Following configuration is an example of using Open Props (e.g. `color:$blue-1`):\n  postcss: {\n    plugins: [postcssJitProps(OpenProps)],\n  },\n};\n```\n\nSee [src/aliases/default.ts](https://github.com/luncheon/isaaccss/blob/main/src/aliases/default.ts) for the default aliases.\n\n## Intention\n\n- Like inline styles and other atomic CSS frameworks:\n  - Predictable changes\n  - No pondering class names\n  - Correct separation of concerns: markup and its style are strongly coupled and should be maintained together. Putting them into separate files is a bad idea.\n- Unlike inline styles:\n  - Media queries, container queries and selectors (combinators, pseudo-class, pseudo-elements) can be described\n  - Specificity can be adjusted\n  - Short aliases can be used\n  - [`Content-Security-Policy`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy): no need `'unsafe-inline'` or `'nonce-a682b15c'` for [`style-src`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy/style-src)\n- Unlike [Tailwind CSS](https://tailwindcss.com/) and [Windi CSS](https://windicss.org/):\n  - This is a class name description rule, not a predefined property set, therefore:\n    - Less to remember\n    - Simple and flexible: any media, any container, any selector, any property and any value can be described as is\n  - High specificity (ID-specificity = 1) by default to override styles from other CSS libraries\n  - Specificity can be adjusted\n  - Class names can be compressed into prefixed short names such as `#a`, `#b`, ..., `#aa`, ...\n  - Invalid class names can be detected\n- Unlike [Linaria](https://linaria.dev/):\n  - Short aliases can be used\n  - Atomic styles are reused, preventing CSS file size bloating\n\n## License\n\n[WTFPL](http://www.wtfpl.net/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluncheon%2Fisaaccss","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fluncheon%2Fisaaccss","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluncheon%2Fisaaccss/lists"}